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]: 與配置系統的整合
