C# .NET core将命令行参数从Program.cs传递到Startup.cs
我正在尝试配置kestrel,使其在原始模式下在特定端口上运行。但是,要做到这一点,launchsettings.json似乎需要传递命令行args,因为没有直接向上选项,它总是在端口5000上运行,如果您有需要运行的api和网站,这显然会发生冲突 因此,我将CommandLine包添加到我的站点,您确实可以在startup.cs文件中使用builder.AddCommandLine() 问题是如何将参数从program.cs获取到Startup.cs,或者查找它们而不是静态变量 如果无法获取args,扩展方法就会变得毫无意义C# .NET core将命令行参数从Program.cs传递到Startup.cs,c#,.net-core,C#,.net Core,我正在尝试配置kestrel,使其在原始模式下在特定端口上运行。但是,要做到这一点,launchsettings.json似乎需要传递命令行args,因为没有直接向上选项,它总是在端口5000上运行,如果您有需要运行的api和网站,这显然会发生冲突 因此,我将CommandLine包添加到我的站点,您确实可以在startup.cs文件中使用builder.AddCommandLine() 问题是如何将参数从program.cs获取到Startup.cs,或者查找它们而不是静态变量 如果无法获取a
有更好的方法吗?Kestrel可以通过多种方式配置为在不同的端口上侦听。这些方法都不需要出现在
Startup
类中,而是出现在Program
类的Main
方法中。使用AddCommandLine
扩展方法就是其中之一。要使用该方法,请修改Program.cs文件的Main
方法,使其如下所示:
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
host.Run();
}
此示例将使您的应用程序在所有可用IP地址上侦听端口
8080
。UPDATE
事实上,我找到了一个似乎更优雅的解决方案:
IConfigurationRoot
(使用CommandLineApplication、好文章和示例)IConfigurationRoot
传递到Startup
public static IWebHost BuildWebHost(string[] args)
{
var configuration = LoadConfiguration(args);
// Use Startup as always, register IConfigurationRoot to services
return new WebHostBuilder()
.UseKestrel()
.UseConfiguration(configuration)
.ConfigureServices(s => s.AddSingleton<IConfigurationRoot>(configuration))
.UseStartup<Startup>()
.Build();
}
public class Startup
{
public Startup(IConfigurationRoot configuration)
{
// You get configuration in Startup constructor or wherever you need
}
}
旧答案
您可以自己实例化Startup类,并将其作为实例传递给WebHostBuilder。这有点不那么优雅,但可行。从
公共静态IWebHost BuildWebHost(字符串[]args)
{
//加载配置并附加命令行参数
var config=new ConfigurationBuilder()
.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutionGassembly().Location))
.AddJsonFile(“configuration.json”)
.AddCommandLine(args)
.Build();
//将配置传递给启动实例
var startup=新启动(配置);
//而不是使用UseStartup()
//向服务注册启动
返回新的WebHostBuilder()
.UseKestrel()
.UseSetting(“applicationName”,“Your.Assembly.Name”)
.UseConfiguration(配置)
.ConfigureServices(服务=>services.AddSingleton(启动))
.Build();
}
需要注意的几点是:
- 通过这样做,启动程序应该实现
,它将参数中的IStartup
方法限制为仅Configure
而不是完整的Configure(IApplicationBuilder应用程序)
Configure(IApplicationBuilder应用程序、IHostingEnvironment环境、ILoggerFactory、IApplicationLifetime生命周期)
- 出于某种原因,您需要手动指定
参数,如我的示例所示。我正在applicationName
2.0.0-preview1-final
- 一个简单的解决方案是通过方法访问命令行参数
您只需确保删除第一个参数,即可执行文件名:
公共类启动
{
公共启动(IHostingEnvironment环境)
{
var args=Environment.GetCommandLineArgs().Skip(1.ToArray();
var builder=new ConfigurationBuilder();
builder.AddCommandLine(args);
Configuration=builder.Build();
}
}
您是否尝试使用命令行上指定的端口运行应用程序,像dotnet运行myproject--port 3333
?是的,或者让vs.Net或vs.code指定一个唯一的端口,这样两个站点可以同时运行。我的问题是,现在启动与startup.cs分离,注入用于测试的内容在正确意义上不再可能,因为配置创建是在main中进行的,而不是在main中启动。另外,使用URL似乎也不错,但我希望这不会影响azure部署?如果使用AddCommandLine选项,它不应该干扰azure部署,因为只有在命令行上指定了端口,它才会更改端口。确定,但这仍然会将配置创建与startup.cs和di解耦。@DanielGrim他需要将命令行参数传递给startup,您的解决方案不会解决这个问题。Yuk,但ok。这些东西应该在vs.net 2017中简单地实现和设置。但不,这是一个黑客。
public static IWebHost BuildWebHost(string[] args)
{
var configuration = LoadConfiguration(args);
// Use Startup as always, register IConfigurationRoot to services
return new WebHostBuilder()
.UseKestrel()
.UseConfiguration(configuration)
.ConfigureServices(s => s.AddSingleton<IConfigurationRoot>(configuration))
.UseStartup<Startup>()
.Build();
}
public class Startup
{
public Startup(IConfigurationRoot configuration)
{
// You get configuration in Startup constructor or wherever you need
}
}
private static IConfigurationRoot LoadConfiguration(string[] args)
{
var configurationFileName = "configuration.json";
var cla = new CommandLineApplication(throwOnUnexpectedArg: true);
var configFileOption = cla.Option("--config <configuration_filename>", "File name of configuration", CommandOptionType.SingleValue);
cla.OnExecute(() =>
{
if (configFileOption.HasValue())
configurationFileName = configFileOption.Value();
return 0;
});
cla.Execute(args);
return new ConfigurationBuilder()
.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.AddJsonFile(configurationFileName, optional: false, reloadOnChange: true)
.AddCommandLine(args)
.Build();
}
public static IWebHost BuildWebHost(string[] args)
{
// Load configuration and append command line args
var config = new ConfigurationBuilder()
.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.AddJsonFile("configuration.json")
.AddCommandLine(args)
.Build();
// pass config to Startup instance
var startup = new Startup(config);
// Instead of using UseStartup<Startup>()
// Register startup to services
return new WebHostBuilder()
.UseKestrel()
.UseSetting("applicationName", "Your.Assembly.Name")
.UseConfiguration(config)
.ConfigureServices(services => services.AddSingleton<IStartup>(startup))
.Build();
}