在没有IOptions <T>的情况下从appsettings.json中读取和使用设置吗?

伊利亚·丘马科夫(Ilya Chumakov)

.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>

伊利亚·丘马科夫(Ilya Chumakov)

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>()));
}

备注:

  • Singleton并不懒惰(它总是在启动时实例化)。
  • 如果是单例注册,则会丢失在运行时更新选项的任何能力(.NET Core本机支持使用reloadOnChange选项安装程序重新加载运行时文件:).AddJsonFile("appsettings.json", false, reloadOnChange: true)

如果您确实需要重新加载文件,但仍然不想使用IOptions,请考虑使用瞬态解析。当然,按请求解决可能会导致性能显着下降。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在没有 appsettings 部分的情况下使用 AddMicrosoftIdentityWebApiAuthentication?

julia 中的“where T”在 T 之后没有任何说明的情况下做什么?

在没有C ++ 11的情况下使用char16_t,char32_t等?

使用 T-SQL 在没有聚合的情况下将多行转换为多列

在没有T的情况下将Task <T>强制转换为C#中的Task <object>

在没有exe的情况下读取WinDBG中的符号

可以在没有分支的情况下使用git吗?

是否有内置方法可以在没有 IOptions 的情况下进行配置模型绑定验证?

在mingw-w64 gcc 7.1中,如何在没有警告的情况下printf size_t?

在没有root的情况下使用chuser和stopudt

在没有Maven的情况下使用JSON

在这种情况下如何在没有 class 或 id 的情况下使用 beautifulsoup

如何在没有 Python 的情况下读取 .py

拐角不同的情况下没有绘制背景吗?

可以在没有GUI的情况下运行JProfiler吗?

在没有makefile的情况下如何设置“ make”命令?

在没有jquery的情况下监听onkeyup和onchange

在没有GHC和阴谋的情况下运行Keter

在没有警告的情况下替换和填充列

在没有HTTP请求的情况下加载JSON

XStream在没有根节点的情况下解析JSON

在没有密钥名称的情况下更改json值

等待JSON API在没有Docker的情况下加载

在Java中没有重点的情况下监听输入

在C中没有pthread的情况下测量开销

在CockroachDB中没有锁的情况下提交

在Postgres中没有停机的情况下进行修补

在没有 CTE 的情况下删除 MySql 中的多行

在没有焦点的情况下监控 tkinter 中的按键