.NET Core允许从配置文件中懒惰地读取设置,将其反序列化为POCO,然后使用一行代码在内置DI容器中注册该POCO:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration.GetSection("MySection"));
}
然后,任何消费者都可以决定IOptions<MyOptions>
访问该POCO:
public HomeController(IOptions<MyOptions> optionsAccessor)
{
MyOptions options = optionsAccessor.Value;
}
这种方法有很多缺点:
Microsoft.Extensions.Options
软件包的不必要依赖:
模拟,测试和显式实例创建变得更加冗长。
解决没有选项的最简单解决方案是什么IOptions<T>
?
用configuration.Get<TOptions>
或反序列化选项,或configuration.Bind
在DI容器中将POCO明确注册为单例:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingletonFromFile<MyOptions>(Configuration.GetSection("MySection"));
}
//...
public static IServiceCollection AddSingletonFromFile<TOptions>(
this IServiceCollection services,
IConfiguration configuration)
where TOptions : class, new()
{
//POCO is created with actual values
TOptions options = configuration.Get<TOptions>();
services.AddSingleton(options);
return services;
}
UPD:感谢@NPNelson的.Get<TOptions>()
提示。
然后IOptions<T>
不再需要解析,并且类依赖关系变得清晰起来:
public HomeController(MyOptions options)
{
_options = options;
}
仅供参考:也可以通过以下方式从外部服务(数据库等)中进行读取:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransientFromService<OptionsReader, MyOptions>(reader => reader.GetOptions());
}
//...
public static void AddTransientFromService<TReader, TOptions>(
this IServiceCollection services,
Func<TReader, TOptions> getOptions)
where TReader : class
where TOptions : class
{
services.AddTransient(provider => getOptions(provider.GetService<TReader>()));
}
备注:
reloadOnChange
选项安装程序重新加载运行时文件:).AddJsonFile("appsettings.json", false, reloadOnChange: true)
;如果您确实需要重新加载文件,但仍然不想使用IOptions
,请考虑使用瞬态解析。当然,按请求解决可能会导致性能显着下降。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句