.NET core 将命令行参数从 Program.cs 传递到 Startup.cs [英] .NET core Pass Commandline Args to Startup.cs from Program.cs

查看:19
本文介绍了.NET core 将命令行参数从 Program.cs 传递到 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.

所以我将命令行包添加到我的站点,您确实可以在 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.

如果您无法获得参数,那么扩展方法就会变得毫无意义.

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

有没有更好的方法来做到这一点?

Any better ways of doing this?

推荐答案

UPDATE

我实际上找到了看起来更优雅的解决方案:

I actually found what seems more elegant solution:

  1. 将命令行参数解析为程序中的 IConfigurationRoot(使用 CommandLineApplication,好文章和示例 这里)
  2. 只需通过 DI 容器将此 IConfigurationRoot 传递给 Startup.
  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();
}

几个注意事项是:

  • 通过这样做,Startup 应该实现 IStartup,它被限制在 Configure 方法的参数中,只有 Configure(IApplicationBuilder app) 而不是完整的Configure(IApplicationBuilder app, 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 core 将命令行参数从 Program.cs 传递到 Startup.cs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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