在 .NET 6 控制台应用程序中工作,并且在将设置从 appsettings.json 绑定到 IOptions 时遇到问题。
这是我的代码:
appsettings.json
{
"MyOptionsSettings" : {
"Foo": 100,
"Bar": true
}
}
我的选项.cs
public class MyOptions
{
public int Foo {get; set;}
public bool Bar {get; set;}
}
程序.cs
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
var builder = Host.CreateDefaultBuilder(args);
builder.ConfigureServices((hostContext, services) =>
{
var configuration = hostContext.Configuration;
services.Configure<MyOptions>(opts => configuration.GetSection("MyOptionsSettings"));
services.AddTransient<MyService>();
});
var app = builder.Build();
var myService = app.Services.GetService<MyService>();
我的服务.cs
public class MyService
{
.
.
public MyService(IOptions<MyOptions> options)
{
_options = options;
}
.
.
}
_options
具有所有属性的默认值,而应用程序设置中没有任何值。我实际上想使用IOptions<T>
包装器IOptionsMonitor<T>
所以设置是动态的。但是,我什至无法获得 IOptions<T>
工作。我想我的问题是IServiceCollection.Configure<T>()
.
更新:
我刚刚看到一个可能解决了我的问题的博客,但我不确定为什么上面的例子没有。根据博客,我更改了以下行:
来自这里:
services.Configure<MyOptions>(opts => configuration.GetSection("MyOptionsSettings"));
为此:
services.Configure<MyOptions>(opts => configuration.GetSection("MyOptionsSettings").Bind(opts));
现在 IOptions 绑定/解析没有任何问题。甚至微软的控制台应用程序文档也使用上面的那个(没有
Bind(opts)
);这两行有什么区别?
OptionsConfigurationServiceCollectionExtensions.Configure
和OptionsServiceCollectionExtensions.Configure
有几个重载前者接受IConfiguration
和后者-Action<TOptions>
,所以第一个将接受从中绑定选项的配置,第二个将需要一些操作填写选项值。所以你的原始片段也可以是:
services.Configure<MyOptions>(configuration.GetSection("MyOptionsSettings")); // IConfigurationSection is IConfiguration
或者您可以使用
Bind
方法,但通常 Action<TOptions>
变体通常用于“手动”配置,例如:
builder.Services.Configure<JsonOptions>(opts =>
opts.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.Never);