在没有IOptions 的情况下从appsettings.json读取和使用设置?
.NET Core 允许从配置文件中懒惰地读取设置,将其反序列化为POCO并使用一行代码在内置DI容器中注册该POCO:
public void ConfigureServices(IServiceCollection services) { services.Configure(Configuration.GetSection("MySection")); }
然后任何消费者都可以解析IOptions
来访问该POCO:
public HomeController(IOptions optionsAccessor) { MyOptions options = optionsAccessor.Value; }
这种方法有明显的缺点:
-
Microsoft.Extensions.Options
包中不必要的依赖项: -
模拟,测试和显式实例创建变得更加冗长。
在没有IOptions
情况下解决选项最简单的解决方案是什么?
使用configuration.Get
或configuration.Bind
调用反序列化选项,并将DI容器中的POCO显式注册为singleton:
public void ConfigureServices(IServiceCollection services) { services.AddSingletonFromFile(Configuration.GetSection("MySection")); } //... public static IServiceCollection AddSingletonFromFile( this IServiceCollection services, IConfiguration configuration) where TOptions : class, new() { //POCO is created with actual values TOptions options = configuration.Get (); services.AddSingleton(options); return services; }
UPD:感谢@NPNelson .Get
提示。
然后不再需要IOptions
解析,并且类依赖性变得清晰:
public HomeController(MyOptions options) { _options = options; }
仅供参考:从外部服务(数据库等)读取也是可能的:
public void ConfigureServices(IServiceCollection services) { services.AddTransientFromService(reader => reader.GetOptions()); } //... public static void AddTransientFromService( this IServiceCollection services, Func getOptions) where TReader : class where TOptions : class { services.AddTransient(provider => getOptions(provider.GetService())); }
备注:
- Singleton不是懒惰的(它总是在启动时实例化);
- 在单例注册的情况下,任何在运行时更新选项的能力都会丢失(.NET Core本身支持使用
reloadOnChange
选项设置重新加载运行时文件:.AddJsonFile("appsettings.json", false, reloadOnChange: true)
);
如果您确实需要重新加载文件但仍然不想使用IOptions
,请考虑进行瞬态解析。 当然,按请求解决可能会导致显着的性能下降。
如果要对依赖于它的unit testing服务进行单元化,则可以模拟IOptions。 看到这个问题及其答案 。 取决于IOptions仍然只取决于接口,因此它不会(或不应该)使您的代码更难以测试。
- 获取实现某个抽象类的所有类
- 将Azure ServiceBus上的消息从.NET Core发送器发送到.NET 4.6处理程序
- RestSharp忽略.NET Core上的系统代理(例如Fiddler)
- SemaphoreSlim保护连接池免于耗尽
- 现在有办法将TVP传递给.Net Core上的小巧玲珑吗?
- 获取.net core 2.1中的usb存储设备的序列号
- 为什么Finalize / Destructor示例在.NET Core中不起作用?
- Microsoft.DotNet.Common.Targets(262,5):错误:对象引用未设置为对象的实例
- 如何在.NET Core中使用HttpClientHandler和HttpClientFactory