D-12 設定擋 ? configuration ? IOptionsMonitor

設定檔

昨日說明關於使用者身分驗證以及權限設定的部分加以說明,並且透過第三方插件的方式展現如何在dotnetcore裡面實作jwt的協定,然而今天會處理甚麼問題呢,請大家看下去。

如何處理設定檔

「糟糕,我要怎麼去把連線串抽出去給SRE設定阿。」
一大早小光到公司時就看到大頭似乎又遇到了問題,可能是昨天寫的東西需要連線到資料庫但是沒有地方可以存放連線串。
「前輩阿,我要把連線串放哪裡啊?」
這時候大頭直接走向老K那邊,直接跟老K請教關於連線串該如何處理。
「很簡單啊,你就放文字檔就好了啊,到時再去讀取文字檔即可。」
聽到老K的說明後大頭似乎有想法的回到座位上準備開始開發的樣子,這時老K快步走到大頭身邊。
「等等~~~你準備怎麼做阿,應該不是寫一個讀檔的功能然後把資料放在記憶體裡面吧。」
大頭的表情一副是你怎麼知道,然後就是有甚麼問題嗎。
「唉,你又想要自己處理設定資料得存放跟動態加載嗎,其實你只要使用IOptionsMonitor跟Configuration就搞定了。」
不過老K說了之後對於大頭而言好像甚麼都沒說的樣子,所以老K就捲起袖子準備大展身手的樣子。
「來吧我示範給你看吧。」

Configuration

所以首先第一動是先把檔案加載進來放在記憶體裡面,這部分就是dotnetcore內建的設定檔的部分,這部分首先是在Program.CreateHostBuilder加入以下內容。

public static IWebHostBuilder CreateHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddJsonFile(
                "Settings/CommonSetting.json", optional: false, reloadOnChange: true);
        });

首先UseContentRoot是設定網頁伺服器的跟目錄,ConfigureAppConfiguration傳的Lambda就是要載入的設定檔,其中:

  • optional -> 是否為選用,如果一定要有這當案就把他設成false但是如過不需要強制讀這檔案就設成true
  • reloadOnChange -> 是否支援動態加載,存檔後記憶體內檔案內容會更新。

接下來如果要依據環境不同資料要不同的話請看下列範例。

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile(
        "Settings/CommonSetting.json", optional: false, reloadOnChange: true);
    var env = hostingContext.HostingEnvironment;
    config.AddJsonFile(
        $"Settings/CommonSetting.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
});

如此可以取得環境變數HostingEnvironment,所以只要在多一個CommonSetting.SIT.json就可以在SIT環境使用了。

IOptionsMonitor

如果不介意直接相依於Configuration以及不會覺得取出來資料還要解析的朋友們恭喜了,因為本篇的內容到上面就結束了。不過想要需要將設定檔解析成類別物件的就繼續看下去。
接下來要說明選項模式,在繼續下去之前要請大家先安裝下面的套件。

dotnet add package Microsoft.Extensions.Options
然後接下來要先說明選項模式中的三種模式
IOptions 檔案變動時資料不會跟著變動
IOptionsSnapshot 注入之後內容就不會變動,但是檔案異動後所注入的資料就是異動後的資料
IOptionsMonitor 支援熱重載,可以適用在單例(Singleton)模式的物件

在說明完種類後現在要開始說明如何把資料放到選項模式物件中。

Configuration跟IOptionsMonitor的橋接

這部分說明怎麼把資料從Configuration註冊到IOptionsMonitor物件中,

首先我們先定義一個類別如下,

public class CommonSetting
{
    public string Connection { get; set; }
}

接下來要再Startup.ConfigureServices加入以下內容。

services.AddOptions();
services.Configure<CommonSetting>(Configuration.GetSection("CommonSetting"));
services.Configure<List<CommonSetting>>(Configuration.GetSection("CommonSettings"));

所以當你的設定檔中有以下內容就可以取得資料並成功注入

{
  "CommonSetting":{
      "Connections":"....."
  }
  "CommonSettings": [{
       "Connections":"....."
     },{
       "Connections":"....."
     }
  ],
}

最後以IOptionsMonitor為例說明如何在物件時例中使用,請先看以下說明。

public class HomeController : Controller
{
    private readonly IOptionsMonitor<CommonSetting> _setting;

    private readonly IOptionsMonitor<List<CommonSetting>> _settings;

    public HomeController(IOptionsMonitor<CommonSetting> setting,
        IOptionsMonitor<List<CommonSetting>> settings)
    {
        setting = _setting;
        settings = _settings;
    }

    public IActionResult Index()
    {
        _setting.CurrentValue.Connection;
        foreach(var item in _settings.CurrentValue)
        {
        }
    }
}

簡單說明就是透過建構子注入之後使用.CurrentValue可以取的最新的資料並做對應的使用即可。

後記

今天跟大家介紹如果有需要使用設定檔該如何透過Microsoft.Extensions.Options這個套件來解析設定檔並且當設定檔異動時可以取得異動後的資訊,希望能對大家的開發有所幫助。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *