.NET核心从Program.cs将命令行Args传递给Startup.cs [英] .NET core Pass Commandline Args to Startup.cs from Program.cs

查看:142
本文介绍了.NET核心从Program.cs将命令行Args传递给Startup.cs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试配置kestrel,以使其处于原始模式时可以在特定端口上运行。但是,这样做似乎launchsettings.json需要传递命令行参数来执行此操作,因为没有直接的选项,并且它始终在端口5000上运行,如果您有需要运行的api和网站,则该端口显然会冲突

I'm trying to configure kestrel so that when it's in it's raw mode it runs on a specific port. However to do so it appears that the launchsettings.json needs to pass command line args to do so since there is no straight up option and it always runs on port 5000 which will obviously conflict if you have an api you need to run and a website.

所以我将CommandLine包添加到了我的站点,您确实可以在startup.cs文件中使用builder.AddCommandLine()。

So I added the CommandLine package to my site and you can indeed use builder.AddCommandLine() in the startup.cs file.

问题在于如何将args从program.cs获取到Startup.cs或查找它们而不是静态变量。

The problem is how to get the args from the program.cs to the Startup.cs or look them up other than a static variable.

如果您无法使用args,这种扩展方法将毫无意义。

Kind of makes the extension method pointless if you can't get at the args.

有更好的方法吗?

推荐答案

更新

我实际上找到了似乎更优雅的解决方案:

I actually found what seems more elegant solution:


  1. 将命令行参数解析到Program中的 IConfigurationRoot 中(使用CommandLineApplication,优秀文章和示例此处

  2. 只需将此 IConfigurationRoot 传递给启动通过DI容器。

  1. Parse command line arguments into IConfigurationRoot in Program (using CommandLineApplication, good article & examples here)
  2. Just pass this IConfigurationRoot to Startup via DI container.

就像这样:

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
    }
}

LoadConfiguration的示例实现,可解析args和构建 IConfigurationRoot (在此示例中,配置文件名可以在命令行参数中覆盖):

Example implementation of LoadConfiguration, which parses args and builds IConfigurationRoot (in this example configuration file name can be overridden in command line arguments):

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();
}

老答案

您可以自己实例化Startup类,并将其作为实例传递给WebHostBuilder。它不是那么优雅,但可行。来自此处。

You can instantiate Startup class by yourself and pass it as instances to WebHostBuilder. It is somewhat not so elegant, but doable. From here.

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();
}

需要注意的是:


  • 这样,启动应实现 IStartup ,该功能仅限于 Configure 参数中的方法仅使用 Configure(IApplicationBuilder应用程序)而不是完整的 Configure(IApplicationBuilder应用程序,IHostingEnvironment env,ILoggerFactory loggerFactory,IApplicationLifetime生存期)

  • 由于某些原因,您需要像我的示例中那样手动指定 applicationName 参数。我正在 2.0.0-preview1-final

  • by doing so, Startup should implement IStartup which is limited for Configure method in parameters to only Configure(IApplicationBuilder app) instead of full Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime lifetime)
  • For some reason, you need to specify applicationName parameter manually as in my example. I'm testing this on 2.0.0-preview1-final

这篇关于.NET核心从Program.cs将命令行Args传递给Startup.cs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆