非常感谢您的评论和指导!
我的目标是将
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";
}
将
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
界面使用。
我建议使用
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();
}
}