1. 程式人生 > 實用技巧 >配置繫結和自定義配置資料來源

配置繫結和自定義配置資料來源

使用強型別物件承載配置資料

元件包:Microsoft.Extensions.Configuration.Binder

要點

  • 支援將配置值繫結到已有物件
  • 支援將配置值繫結到私有屬性上

準備工作:

定義一個類來作為接受配置的例項 Config.cs

public class Config
{
    public string Key1 { get; set; }
    public int Key2 { get; set; }
    public bool Key3 { get; set; }

}

配置檔案 MyJson.json

{
"key1": "Hello",
"Key2
": 1, "key3": true, "key4":"Null" }

將元件包引用後,構造一個Config來接受配置檔案:

讀取分層的配置檔案:

MyJson.json

{
  "key1": "Hello",
  "Key2": 1,
  "key3": true,
  "key4": "Null",
  "section": {
    "key" : "key in section" 
  } 
}

我們想要讀取section塊裡的資訊,則先利用GetSection()方法返回具有指定子節鍵的配置子節後在進行繫結。

當我們的型別變數為Private Set時, 我們想要從配置檔案中繫結該值,則需要在Bind方法中設定Options。


自定義配置資料來源

拓展步驟

  • 實現 IConfigurationSource
  • 實現 IConfigurationProvider
  • 實現 AddXXX擴充套件方法

MyConfigurationSource: 用來返回我們自定義的Provider

class MyConfigurationSource : IConfigurationSource
{
    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new MyConfigurationProvider();
    }
}

MyConfigurationProvider: 利用執行緒每三秒改變讀取當前時間,模擬配置源的變更。

public MyConfigurationProvider() : base()
{
    var timer = new Timer();
    timer.Elapsed += Timer_Elapsed;
    timer.Interval = 3000;
    timer.Start();
}

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
    Load(true);
}

public override void Load()
{
    //載入資料
    Load(false);
}

void Load(bool reload)
{
    this.Data["lastTime"] = DateTime.Now.ToString(CultureInfo.CurrentCulture);
    if (reload)
    {
        base.OnReload();
    }
}

這個時候我們的擴充套件就大概完成了,我們可以通過builder.Add(new ConfigurationSource())來獲取我們的自定義配置,但並不建議這樣注入。因為這樣我們必須將Provider設為Public暴露給第三方。

正確的且官方建議的做法應該為:設定一個擴充套件方法將配置源新增進ConfigurationBuilder.

public static IConfigurationBuilder AddMyConfiguration(this IConfigurationBuilder builder)
        {
            builder.Add(new MyConfigurationSource());
            return builder;
        }

Program.cs

class Program
{
    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder();
        builder.AddMyConfiguration();

        var configRoot = builder.Build();

        ChangeToken.OnChange(() => configRoot.GetReloadToken(), () =>
        {
            Console.WriteLine($"lastTime:{configRoot["lastTime"]}");
        });

        Console.WriteLine("開始了");
        Console.ReadKey();
    }
}

在我們定義我們的擴充套件的時候,建議是將具體的實現都定義成私有的,然後通過擴充套件方法的方式暴露出去。

利用ChangeToken的OnChange事件來監聽配置源的變更狀態。