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

标签 c# dependency-injection asp.net-core .net-core

.NET 核心 allows从配置文件中延迟读取设置,将其反序列化为 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;
}

更新:感谢@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 native 支持使用 reloadOnChange 选项设置重新加载运行时文件:.AddJsonFile("appsettings.json", false, reloadOnChange: true));

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

关于c# - 在没有 IOptions<T> 的情况下读取和使用 appsettings.json 中的设置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43679665/

相关文章:

c# - 我如何在 AspNet.Core 中读取 EXIF 数据

C# 将文件保存到服务器上的文件夹而不是本地

c# - 带有 OpenRasta 和 ASP.NET MVC 的 REST API

dependency-injection - 如何在Flutter中手动实现依赖注入(inject)?

c# - 'OFFSET' 附近的语法不正确。 FETCH 语句中 NEXT 选项的无效使用 "in Entity Framework core"

asp.net-core - 在 ASP.NET Core SignalR 中从 TestServer 初始化 HubConnection

c# - 如何使用 C# 正确解析 RAW(Raw Ip) 数据包?

C# 比较速记

java - Spring依赖注入(inject)解决什么问题?

.net - 通过 web.config 对 WCF 服务的 Unity 依赖注入(inject)