将命令行参数传递给ASP Core中的Startup类

时间:2022-04-29 23:15:20

I have arguments passed in via the command-line

我通过命令行传入了参数

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

One of these arguments is a logging output directory. How do I get this value into my Startup class so I can write out to this directory when I receive a request?

其中一个参数是日志输出目录。如何将此值放入我的Startup类中,以便在收到请求时可以写出此目录?

I'd like to avoid using a static class. Would a service that supplies the value be the right way? If so, how do I get services injected into my middleware?

我想避免使用静态类。提供价值的服务是否是正确的方式?如果是这样,我如何将服务注入我的中间件?

3 个解决方案

#1


8  

You should be able to use the AddCommandLine() extension. First install the Nuget package Microsoft.Extensions.Configuration.CommandLine and ensure you have the correct import:

您应该能够使用AddCommandLine()扩展名。首先安装Nuget包Microsoft.Extensions.Configuration.CommandLine并确保您具有正确的导入:

using Microsoft.Extensions.Configuration;

Now update your Main method to include the new config:

现在更新您的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);

Now you treat the command line options as configuration:

现在,您将命令行选项视为配置:

dotnet run /MySetting:SomeValue=123

And read in code:

并阅读代码:

var someValue = Configuration.GetValue<int>("MySetting:SomeValue");

#2


2  

DavidG's answer is correct, but there were still some pieces of the puzzle missing for me.

DavidG的回答是正确的,但仍然有一些难题不适合我。

There are two Nuget packages you need:

您需要两个Nuget包:

  1. Microsoft.Extensions.Configuration.Binder
  2. Microsoft.Extensions.Configuration.CommandLine

Because we want the command line arguments, we need to create the configuration in the Main(string[]).

因为我们需要命令行参数,所以我们需要在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;
    }
}

The Startup class is:

Startup类是:

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

Is the command argument are --port 6000 outputDirectory C:\Temp then this will output:

命令参数是--port 6000 outputDirectory C:\ Temp然后这将输出:

port            :6000
outputDirectory :C:\Temp

#3


2  

ASP.NET Core 2 answer:

ASP.NET Core 2答案:

Change the default Program.cs to be:

将默认的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();
}

I removed other bits just to make the configuration explanation easier.

我删除了其他位只是为了使配置说明更容易。

Note the .AddCommandLine(args) line in the configuration builder.

请注意配置构建器中的.AddCommandLine(args)行。

Unlike @BanksySan's answer you DON'T need to create a static property, instead let DI inject the IConfiguration into the startup class.

与@ BanksySan的答案不同,您不需要创建静态属性,而是让DI将IConfiguration注入启动类。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    private IConfiguration Configuration { get; }

You can now use the configuration entries from any of the config providers, file, env variables and commandline.

您现在可以使用任何配置提供程序,文件,env变量和命令行中的配置条目。

Example:

dotnet run --seed true

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

Hope this helps someone further.

希望这有助于进一步发展。

#1


8  

You should be able to use the AddCommandLine() extension. First install the Nuget package Microsoft.Extensions.Configuration.CommandLine and ensure you have the correct import:

您应该能够使用AddCommandLine()扩展名。首先安装Nuget包Microsoft.Extensions.Configuration.CommandLine并确保您具有正确的导入:

using Microsoft.Extensions.Configuration;

Now update your Main method to include the new config:

现在更新您的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);

Now you treat the command line options as configuration:

现在,您将命令行选项视为配置:

dotnet run /MySetting:SomeValue=123

And read in code:

并阅读代码:

var someValue = Configuration.GetValue<int>("MySetting:SomeValue");

#2


2  

DavidG's answer is correct, but there were still some pieces of the puzzle missing for me.

DavidG的回答是正确的,但仍然有一些难题不适合我。

There are two Nuget packages you need:

您需要两个Nuget包:

  1. Microsoft.Extensions.Configuration.Binder
  2. Microsoft.Extensions.Configuration.CommandLine

Because we want the command line arguments, we need to create the configuration in the Main(string[]).

因为我们需要命令行参数,所以我们需要在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;
    }
}

The Startup class is:

Startup类是:

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

Is the command argument are --port 6000 outputDirectory C:\Temp then this will output:

命令参数是--port 6000 outputDirectory C:\ Temp然后这将输出:

port            :6000
outputDirectory :C:\Temp

#3


2  

ASP.NET Core 2 answer:

ASP.NET Core 2答案:

Change the default Program.cs to be:

将默认的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();
}

I removed other bits just to make the configuration explanation easier.

我删除了其他位只是为了使配置说明更容易。

Note the .AddCommandLine(args) line in the configuration builder.

请注意配置构建器中的.AddCommandLine(args)行。

Unlike @BanksySan's answer you DON'T need to create a static property, instead let DI inject the IConfiguration into the startup class.

与@ BanksySan的答案不同,您不需要创建静态属性,而是让DI将IConfiguration注入启动类。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    private IConfiguration Configuration { get; }

You can now use the configuration entries from any of the config providers, file, env variables and commandline.

您现在可以使用任何配置提供程序,文件,env变量和命令行中的配置条目。

Example:

dotnet run --seed true

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

Hope this helps someone further.

希望这有助于进一步发展。