将命令行参数传递给 Startup class in ASP.NET Core
Pass command-line arguments to Startup class in ASP.NET Core
我有通过命令行传入的参数
private static int Main(string[] args)
{
const string PORT = "12345" ;
var listeningUrl = $"http://localhost:{PORT}";
var builder = new WebHostBuilder()
.UseStartup<Startup>()
.UseKestrel()
.UseUrls(listeningUrl);
var host = builder.Build();
WriteLine($"Running on {PORT}");
host.Run();
return 0;
}
其中一个参数是日志输出目录。我如何将这个值放入我的 Startup
class 以便我可以在收到请求时写入此目录?
我想避免使用静态 class。提供价值的服务是正确的方式吗?如果是这样,我如何将服务注入我的中间件?
您应该可以使用 AddCommandLine()
扩展程序。首先安装 Nuget 包 Microsoft.Extensions.Configuration.CommandLine
并确保你有正确的导入:
using Microsoft.Extensions.Configuration;
现在更新您的 Main
方法以包含新配置:
var config = new ConfigurationBuilder()
.AddJsonFile("hosting.json", optional: true) //this is not needed, but could be useful
.AddCommandLine(args)
.Build();
var builder = new WebHostBuilder()
.UseConfiguration(config) //<-- Add this
.UseStartup<Startup>()
.UseKestrel()
.UseUrls(listeningUrl);
现在您将命令行选项视为配置:
dotnet run /MySetting:SomeValue=123
并读入代码:
var someValue = Configuration.GetValue<int>("MySetting:SomeValue");
是正确的,但我仍然缺少一些拼图。
您需要两个 Nuget 包:
Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.Configuration.CommandLine
因为我们需要命令行参数,所以我们需要在 Main(string[])
.
中创建配置
using Microsoft.Extensions.Configuration;
class Program
{
private static int Main(string[] args)
{
const string PORT = "12345";
var listeningUrl = $"http://localhost:{PORT}";
var configuration = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
// Set the `static` `Configuration` property on the `Startup` class.
Startup.Configuration = configuration;
var builder = new WebHostBuilder()
.UseStartup<Startup>()
.UseKestrel()
.UseSetting("Message", "Hello World")
.UseUrls(listeningUrl);
var host = builder.Build();
WriteLine($"Running on {listeningUrl}");
host.Run();
return SUCCESS_EXIT_CODE;
}
}
Startup
class是:
using Microsoft.Extensions.Configuration;
public class Startup
{
public static IConfiguration Configuration { get; set; }
public void Configure(IApplicationBuilder app)
{
foreach (var c in Configuration.AsEnumerable())
Console.WriteLine($"{c.Key,-15}:{c.Value}");
}
}
如果命令参数是 --port 6000 outputDirectory C:\Temp
那么这将输出:
port :6000
outputDirectory :C:\Temp
ASP.NET核心2答案:
将默认 Program.cs 更改为:
using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
config.AddEnvironmentVariables();
config.AddCommandLine(args);
})
.UseStartup<Startup>()
.Build();
}
我删除了其他位只是为了使配置解释更容易。
注意配置生成器中的 .AddCommandLine(args)
行。
与@BanksySan 的回答不同,您不需要创建静态 属性,而是让 DI 将 IConfiguration 注入启动 class。
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
private IConfiguration Configuration { get; }
您现在可以使用来自任何配置提供程序、文件、环境变量和命令行的配置条目。
示例:
dotnet 运行 --seed true
public void Configure(IApplicationBuilder app)
{
app.UseExceptionHandler("/Home/Error");
var seed = Configuration.GetValue<bool>("seed");
if (seed)
SeedData.Initialize(app);
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
希望这对其他人有帮助。
网络核心 2
您不需要 dotnet core 1.0 中的大部分代码即可实现此目的。
AddCommandLine
使用以下语法构建 WebHost 时会自动注入参数
步骤 1.
public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
第 2 步。使用以下代码
使用 DI 将配置注入 Startup.cs
public class Startup
{
private readonly IConfiguration Configuration;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
...
}
第 3 步。使用配置对象访问您的参数。
var seed = Configuration.GetValue<bool>("seed");
Console.WriteLine($"seed: {seed}");
第 4 步。使用参数启动应用程序
dotnet run seed=True
如果您只需要将原始命令行参数传递给进程,或者您不想将它们添加到配置中,您仍然可以使用以下方法:
Environment.GetCommandLineArgs();
我有通过命令行传入的参数
private static int Main(string[] args)
{
const string PORT = "12345" ;
var listeningUrl = $"http://localhost:{PORT}";
var builder = new WebHostBuilder()
.UseStartup<Startup>()
.UseKestrel()
.UseUrls(listeningUrl);
var host = builder.Build();
WriteLine($"Running on {PORT}");
host.Run();
return 0;
}
其中一个参数是日志输出目录。我如何将这个值放入我的 Startup
class 以便我可以在收到请求时写入此目录?
我想避免使用静态 class。提供价值的服务是正确的方式吗?如果是这样,我如何将服务注入我的中间件?
您应该可以使用 AddCommandLine()
扩展程序。首先安装 Nuget 包 Microsoft.Extensions.Configuration.CommandLine
并确保你有正确的导入:
using Microsoft.Extensions.Configuration;
现在更新您的 Main
方法以包含新配置:
var config = new ConfigurationBuilder()
.AddJsonFile("hosting.json", optional: true) //this is not needed, but could be useful
.AddCommandLine(args)
.Build();
var builder = new WebHostBuilder()
.UseConfiguration(config) //<-- Add this
.UseStartup<Startup>()
.UseKestrel()
.UseUrls(listeningUrl);
现在您将命令行选项视为配置:
dotnet run /MySetting:SomeValue=123
并读入代码:
var someValue = Configuration.GetValue<int>("MySetting:SomeValue");
您需要两个 Nuget 包:
Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.Configuration.CommandLine
因为我们需要命令行参数,所以我们需要在 Main(string[])
.
using Microsoft.Extensions.Configuration;
class Program
{
private static int Main(string[] args)
{
const string PORT = "12345";
var listeningUrl = $"http://localhost:{PORT}";
var configuration = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
// Set the `static` `Configuration` property on the `Startup` class.
Startup.Configuration = configuration;
var builder = new WebHostBuilder()
.UseStartup<Startup>()
.UseKestrel()
.UseSetting("Message", "Hello World")
.UseUrls(listeningUrl);
var host = builder.Build();
WriteLine($"Running on {listeningUrl}");
host.Run();
return SUCCESS_EXIT_CODE;
}
}
Startup
class是:
using Microsoft.Extensions.Configuration;
public class Startup
{
public static IConfiguration Configuration { get; set; }
public void Configure(IApplicationBuilder app)
{
foreach (var c in Configuration.AsEnumerable())
Console.WriteLine($"{c.Key,-15}:{c.Value}");
}
}
如果命令参数是 --port 6000 outputDirectory C:\Temp
那么这将输出:
port :6000
outputDirectory :C:\Temp
ASP.NET核心2答案:
将默认 Program.cs 更改为:
using System;
using System.IO;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
config.AddEnvironmentVariables();
config.AddCommandLine(args);
})
.UseStartup<Startup>()
.Build();
}
我删除了其他位只是为了使配置解释更容易。
注意配置生成器中的 .AddCommandLine(args)
行。
与@BanksySan 的回答不同,您不需要创建静态 属性,而是让 DI 将 IConfiguration 注入启动 class。
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
private IConfiguration Configuration { get; }
您现在可以使用来自任何配置提供程序、文件、环境变量和命令行的配置条目。
示例:
dotnet 运行 --seed true
public void Configure(IApplicationBuilder app)
{
app.UseExceptionHandler("/Home/Error");
var seed = Configuration.GetValue<bool>("seed");
if (seed)
SeedData.Initialize(app);
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
希望这对其他人有帮助。
网络核心 2
您不需要 dotnet core 1.0 中的大部分代码即可实现此目的。
AddCommandLine
使用以下语法构建 WebHost 时会自动注入参数
步骤 1.
public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
第 2 步。使用以下代码
使用 DI 将配置注入 Startup.cspublic class Startup
{
private readonly IConfiguration Configuration;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
...
}
第 3 步。使用配置对象访问您的参数。
var seed = Configuration.GetValue<bool>("seed");
Console.WriteLine($"seed: {seed}");
第 4 步。使用参数启动应用程序
dotnet run seed=True
如果您只需要将原始命令行参数传递给进程,或者您不想将它们添加到配置中,您仍然可以使用以下方法:
Environment.GetCommandLineArgs();