如何使用“ConfigurationBuilder()”从“launchSettings.json”读取“CommandLineArgument”的值?

问题描述 投票:0回答:1

非常感谢您的评论和指导!

设定

  • c# (net7.0)
  • 控制台应用程序
  • NuGet 包:Microsoft.Extensions.Configuration
  • NuGet 包:Microsoft.Extensions.DependencyInjection
  • NuGet 包:Microsoft.Extensions.Hosting
  • 配置文件:launchSettings.json

目标

我的目标是将

args
存储在自定义设计的类中,同时使用 Microsoft 提供的依赖项注入和配置工具。

问题

Program
args
的内容符合预期。
如果我迭代数组
args
,我就可以访问存储在
launchSettings.json
中的成员。第一个成员存储
key
,第二个成员存储
value
"--CommandLineArgument CommandLineStringIsPassedOnByLaunchSettingsJson"

如果我使用代码
builder.Build().GetValue<string>("CommandLineArgument")
,我会收到正确的值。

Startup
中,
CommandLineArgument
的内容是
string.empty
。我期望值 CommandLineStringIsPassedOnByLaunchSettingsJson

问题

我在这里缺少什么?
我在配置部分错过了什么吗?
我在

GetAppSetting
中使用了错误的代码吗?
我假设这两行代码的作用相同 - 这是正确的吗?:
builder.Build().GetValue<string>("CommandLineArgument")

_configuration.GetValue<string>("CommandLineArgument")

完整代码

配置文件

launchSetting.json
.

{
  "profiles": {
    "StackOverflow": {
      "commandName": "Project",
      "commandLineArgs": "--CommandLineArgument CommandLineStringIsPassedOnByLaunchSettingsJson",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Development"
      }
    }
  }
}

Program

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using StackOverflow;

var builder = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddEnvironmentVariables()
    .AddCommandLine(args);

Console.WriteLine($"\n*** Program.Main() ***");
foreach (var item in args)
{
    Console.WriteLine($"Commandline Argument (collection of 'args'): {item}");
}

using var host = Host.CreateDefaultBuilder()
    .ConfigureServices((context, services) =>
    {
        services.AddTransient<IStartup, Startup>();
        services.AddTransient<IAppSettingProvider, AppSettingProvider>();
    })
    .Build();

using var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;

Console.WriteLine($"Commandline Argument ('Build().GetValue()'): {builder.Build().GetValue<string>("CommandLineArgument")}");

services.GetRequiredService<IStartup>().Run();

Console.WriteLine($"\n***** Press ENTER To End The Application *****");
Console.ReadLine();

IAppSettingProvider

namespace StackOverflow;

public interface IAppSettingProvider
{
    AppSetting GetAppSetting();
}

AppSettingProvider

using Microsoft.Extensions.Configuration;

namespace StackOverflow;

public class AppSettingProvider : IAppSettingProvider
{
    private readonly IConfiguration _configuration;

    public AppSettingProvider(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public AppSetting GetAppSetting()
    {
        AppSetting output = new()
        {
            CommandLineArgument = _configuration.GetValue<string>("CommandLineArgument")!,
        };

        return output;
    }
}

IStartup

namespace StackOverflow;

public interface IStartup
{
    void Run();
}

Startup

namespace StackOverflow;

public class Startup : IStartup
{
    public AppSetting AppSetting { get; set; }

    readonly IAppSettingProvider _appSettingProvider;

    public Startup(IAppSettingProvider appSettingProvider)
    {
        _appSettingProvider = appSettingProvider;

        AppSetting = new();
    }

    public void Run()
    {
        Console.WriteLine($"\n*** {nameof(Startup)}.{nameof(Run)}() ***");
        Console.WriteLine($"The value of the command line: {AppSetting.CommandLineArgument}");

        AppSetting = _appSettingProvider.GetAppSetting();
        Console.WriteLine($"The value of the command line: {AppSetting.CommandLineArgument}");

        Console.WriteLine("\nPress ENTER to continue.");
        Console.ReadLine();
    }
}

AppSetting

namespace StackOverflow;

public class AppSetting
{
    public string CommandLineArgument { get; set; } = "default Value";
}
c# dependency-injection configuration
1个回答
0
投票

选项#1

args
参数添加到
Host.CreateDefaultBuilder()
方法中。

using var host =
    Host.CreateDefaultBuilder(args) // <-- add args here
        .ConfigureServices(
            (context, services) =>
            {
                services.AddTransient<IStartup, Startup>();
                services.AddTransient<IAppSettingProvider, AppSettingProvider>();
            }
        )
        .Build();

这样就可以通过

IConfiguration
界面使用。

选项#2

我建议使用

IOptions
功能而不是手动编写
AppSettingProvider

AppSetting.cs
- 和你的一样

namespace StackOverflow;

public class AppSetting
{
    public string CommandLineArgument { get; set; } = "default Value";
}

配置键为

AppSetting:CommandLineArgument
,但您也可以使用双下划线:
AppSetting__CommandLineArgument

launchSettings.json

{
  "profiles": {
    "StackOverflow": {
      "commandName": "Project",
      "commandLineArgs": "--AppSetting__CommandLineArgument CommandLineStringIsPassedOnByLaunchSettingsJson",
      "environmentVariables": {
        "DOTNET_ENVIRONMENT": "Development"
      }
    }
  }
}

然后在

Program.cs
中注册选项。

Program.cs

using var host =
    Host.CreateDefaultBuilder(args) // <-- add args here
        .ConfigureServices(
            (context, services) =>
            {
                // register your settings as options
                services
                    .AddOptions<AppSetting>()
                    .Bind(context.Configuration.GetSection(nameof(AppSetting));

                services.AddTransient<IStartup, Startup>();
                services.AddTransient<IAppSettingProvider, AppSettingProvider>();
            }
        )
        .Build();

然后你将它注射到你体内

Startup

Startup.cs

namespace StackOverflow;

public class Startup : IStartup
{
    private readonly AppSetting appSetting;

    public Startup(IOptions<AppSetting> appSettingOptions)
    {
        appSetting = appSettingOptions.Value;
    }

    public void Run()
    {
        Console.WriteLine($"\n*** {nameof(Startup)}.{nameof(Run)}() ***");

        Console.WriteLine(
            $"The value of the command line: {appSetting.CommandLineArgument}"
        );

        Console.WriteLine("\nPress ENTER to continue.");
        Console.ReadLine();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.