我创建了一个新的 .NET Core 控制台应用程序并安装了以下软件包
我为配置创建了一个 appsettings.json 文件
{
"app": {
"foo": "bar"
}
}
Run Code Online (Sandbox Code Playgroud)
我想将这些值映射到一个类
internal class AppOptions
{
public string Foo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我还想在配置过程中验证选项,因此我添加了一个验证类
internal class AppOptionsValidator : IValidateOptions<AppOptions>
{
public ValidateOptionsResult Validate(string name, AppOptions options)
{
IList<string> validationFailures = new List<string>();
if (string.IsNullOrEmpty(options.Foo))
validationFailures.Add("Foo is required.");
return validationFailures.Any()
? ValidateOptionsResult.Fail(validationFailures)
: ValidateOptionsResult.Success;
}
}
Run Code Online (Sandbox Code Playgroud)
我想设置 DI 容器并创建一个测试场景
static void Main(string[] args)
{
ConfigureServices();
Console.ReadLine();
}
private static void ConfigureServices()
{
IServiceCollection serviceCollection = new ServiceCollection();
IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
// Setup configuration service
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.AddEnvironmentVariables()
.Build();
serviceCollection.AddSingleton(configuration);
// Setup options
IConfiguration configurationFromDI = serviceProvider.GetService<IConfiguration>(); // This is just for testing purposes
IConfigurationSection myConfigurationSection = configurationFromDI.GetSection("app");
serviceCollection.AddSingleton<IValidateOptions<AppOptions>, AppOptionsValidator>();
serviceCollection.Configure<AppOptions>(myConfigurationSection);
// Try to read the current options
IOptions<AppOptions> appOptions = serviceProvider.GetService<IOptions<AppOptions>>();
Console.WriteLine(appOptions.Value.Foo);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是该变量configurationFromDI
为空。因此该变量configuration
没有添加到 DI 容器中。
如何正确设置控制台应用程序的依赖注入?
应在所有服务注册后BuildServiceProvider
进行调用。
不过,没有必要编写所有这些代码。由于您已经使用了如此多的扩展,因此最好(也更容易)使用通用 Host,就像 ASP.NET Core 应用程序使用其ConfigureServices
,ConfigureAppConfiguration
方法一样:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureHostConfiguration(configuration =>
{
configuration....;
});
.ConfigureServices((hostContext, services) =>
{
var myConfigurationSection = configuration.GetSection("app");
services.AddSingleton<IValidateOptions<AppOptions>, AppOptionsValidator>();
services.Configure<AppOptions>(myConfigurationSection);
});
}
Run Code Online (Sandbox Code Playgroud)
可通过HostBuilderContext.Configuration属性进行配置。
CreateDefaultBuilder设置当前文件夹、配置环境变量和文件的使用appsettings.json
,因此无需显式添加它们。
Appsettings.json 复制设置
在 Web 应用程序模板中,appsettings.json
文件会自动添加,Build Action
属性设置为Content
,Copy to Output
操作设置为Copy if Newer
。
控制台应用程序中没有此类文件。appsettings.json
当手动添加新文件时,其Build Action
isNone
和Copy
to Never
。调试应用程序时,当前目录为bin\Debug
. 使用默认设置,appsettings.json
不会被复制到bin/Debug
Build Action
必须更改为Content
且Copy
应设置为Copy if Newer
或Copy Always
。