1. 程式人生 > >[ASP.NET Core 3框架揭祕] Options[7]: 與配置系統的整合

[ASP.NET Core 3框架揭祕] Options[7]: 與配置系統的整合

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