Options 模型本身与配置系统完全没有关系, 但是配置在大部分情况下会作为绑定 Options 对象的数据源, 所以有必要将两者结合在一起. 与《扩展与定制》演示的两个例子一样, 针对配置系统的集成同样是通过定制 Options 模型相应的对象来实现的. 具体来说, 集成配置系统需要解决如下两个问题:
将承载配置数据的 IConfiguration 对象绑定为 Options 对象.
自动感知配置数据的变化.
第一个问题涉及针对 Options 对象的初始化问题, 这自然是通过自定义 IConfigureOptions<TOptions > 实现类型来解决的, 具体来说就是下面的 NamedConfigureFromConfigurationOptions<TOptions > 类型, 它定义在 NuGet 包 "Microsoft.Extensions.Options.ConfigurationExtensions" 中. 如下面的代码片段所示, NamedConfigureFromConfigurationOptions<TOptions > 通过调用 ConfigurationBinder 的静态方法 Bind 利用配置绑定机制来实现配置数据向 Options 对象的转换.
- public class NamedConfigureFromConfigurationOptions<TOptions> : ConfigureNamedOptions<TOptions> where TOptions : class
- {
- public NamedConfigureFromConfigurationOptions(string name, IConfiguration config)
- : base(name, options => ConfigurationBinder.Bind(config, options))
- {}
- }
第二个问题则采用自定义的 IOptionsChangeTokenSource<TOptions > 实现类型来解决, 具体提供的就是下面的 ConfigurationChangeTokenSource<TOptions>. 从给出的代码片段可以看出, GetChangeToken 方法直接调用 IConfiguration 对象的 GetReloadToken 方法得到返回的 IChangeToken 对象.
- public class ConfigurationChangeTokenSource<TOptions> : IOptionsChangeTokenSource<TOptions>
- {
- private IConfiguration _config;
- public string Name { get; }
- public ConfigurationChangeTokenSource(IConfiguration config) : this(Options.DefaultName, config)
- { }
- public ConfigurationChangeTokenSource(string name, IConfiguration config)
- {
- _config = config;
- Name = name ?? Options.DefaultName;
- }
- public IChangeToken GetChangeToken() => _config.GetReloadToken()
- }
将 IConfiguration 对象绑定为 Options 对象的 NamedConfigureFromConfigurationOptions<TOptions > 和用来检测配置数据变化的 ConfigurationChangeTokenSource<TOptions > 都是通过下面的 Configure<TOptions > 扩展方法来注册的.
- public static class OptionsConfigurationServiceCollectionExtensions
- {
- public static IServiceCollection Configure<TOptions>( this IServiceCollection services, IConfiguration config) where TOptions : class
- => services.Configure<TOptions>(Options.Options.DefaultName, config);
- public static IServiceCollection Configure<TOptions>( this IServiceCollection services, string name, IConfiguration config) where TOptions : class
- => services
- .AddSingleton<IOptionsChangeTokenSource<TOptions>>( new ConfigurationChangeTokenSource<TOptions>(name, config))
- .AddSingleton<IConfigureOptions<TOptions>>( new NamedConfigureFromConfigurationOptions<TOptions>(name, config));
- }
[ASP.NET Core 3 框架揭秘] Options[1]: 配置选项的正确使用方式 [上篇]
[ASP.NET Core 3 框架揭秘] Options[2]: 配置选项的正确使用方式 [下篇]
[ASP.NET Core 3 框架揭秘] Options[3]: Options 模型 [上篇]
[ASP.NET Core 3 框架揭秘] Options[4]: Options 模型 [下篇]
[ASP.NET Core 3 框架揭秘] Options[5]: 依赖注入
[ASP.NET Core 3 框架揭秘] Options[6]: 扩展与定制
[ASP.NET Core 3 框架揭秘] Options[7]: 与配置系统的整合
来源: https://www.cnblogs.com/artech/p/inside-asp-net-core-06-07.html