.Net Core Configuration(組態設定)

以往的組態設定方式

相信有寫過.Net Framework MVC 開發專案的人員,都會從專案中的Web.config來取得組態設定,但在.Net Core裡面是已經沒有Web.config檔案了,取而代之的是

  • 組態設定檔(Json ,Xml,INI)
  • 命令列參數
  • 環境變數
  • 自訂的組態提供者 (custom configuration provider)
  • 記憶體中的 .NET 物件
  • 從未加密的 Secret Manager 儲存區取得設定
  • Azure Key Vault

等等的來源,之前在我的文章內也有稍微帶到ASP .NET MVC 5 前進 .NET
這次的紀錄會聚焦在組態設定檔的實作

OK Let's Get Ready To Rumble!!!

Configuration的初步認識

首先我們先開一個專案Empty 的 .Net Core,這也是我很常用來研究.Net 以及要弄清楚各個功能會去開設的專案,原因是要學習一項新的知識,環境越簡單越好,如果開啟預設的.Net Core Web應用程式,它會有很多預設好的文件和設定,這樣對學習來說會變得更加難以理解。

我們在日常專案中會將

  • DB連線字串
  • Client ID
  • API Keys
  • Domain Names
  • Constant email addresses
  • SSMTP 站台的設定

等等放入組態文件appsettings.json中,由於是Key Value的形式,只要前面有個,做分隔 就可以開始定義自己想要的組態的值。

.Net Core Configuration(組態設定)

之後再到Program.cs,啟用我們這次練習會用到的Services 以及 Middleware,預設的app.MapGet(“/”, () => “Hello World!”);這個可以拿掉,不影響我們的操作。

利用 app.Configuration[“MyKey”] 來取得我們在先前appsettings.json定義的MyKey。

app.MapGet("/", async context =>
{
    var appsettingsMyKey = app.Configuration["MyKey"];

    if (appsettingsMyKey is not null)
    {
        await context.Response.WriteAsync(appsettingsMyKey);
    }
    else
    {
        await context.Response.WriteAsync("No Value");
    }
});

我們可以成功地從 MyKey 這個Key值取到我們的 Value值

還有另外一種寫法

我們也可以使用app.Configuration.GetValue<>的方法,來定義要取值的型別,像這邊我使用string型別來取得”MyKey”的Value

app.MapGet("/", async context =>
{
    //var appsettingsMyKey = app.Configuration["MyKey"];
    var appsettingsMyKey = app.Configuration.GetValue<string>("MyKey");

    if (appsettingsMyKey is not null)
    {
        await context.Response.WriteAsync(appsettingsMyKey);
    }
    else
    {
        await context.Response.WriteAsync("No Value");
    }
});

app.Configuration.GetValue<>的方法也可以提供預設值Default value,像以下的例子我提供了第二個參數,也就是Default value

我們的appsettings.json並沒有 x 這個Key,我們將預設值設定為66

app.MapGet("/", async context =>
{
    //var appsettingsMyKey = app.Configuration["MyKey"];
    var appsettingsMyKey = app.Configuration.GetValue<string>("MyKey");
    var numberx = app.Configuration.GetValue<int>("x", 66);

    if (appsettingsMyKey is not null)
    {
        await context.Response.WriteAsync(appsettingsMyKey + "\n");
        await context.Response.WriteAsync(numberx + "\n");
    }
    else
    {
        await context.Response.WriteAsync("No Value");
    }
});

程式運行起來我們也能夠拿到預設值66。


在Controller 或其他地方取得組態設定

在Controller中或其他Class中取得Configuration也是我們平日在專案中比較常見的操作方式

我們先將Program.cs中的app.MapGet 這段註解

在我們練習的專案裡面建立簡單的Controller 跟 View

在Controller內 定義一個 private readonly 的 IConfiguration

透過 constructor DI注入取得IConfiguration的服務

我們用ViewBag來取得組態的值

這邊我故意取我們appsettings.json中沒有設定的Key MyAPI 並且給它一個預設值

View 也是相當簡單,直接把我們的ViewBag帶過來

OK,可以成功取得我們在appsettings.json 設定的組態。

但利用IConfiguration這種方式取值是相對來說比較rough的,但如果在你的專案中也只有一些地方需要使用到,沒有高重複利用的需求這樣的方法也是可以接受的,假如說是使用HttpClient要不停得呼叫API,當中要使用到API的Token這樣的方式可能不太好,我們會使用Options Pattern的方式。


Options Pattern

我們在appsettings.json 再新增一個StripeSetting段落的組態設定

然後定義出一個StripeService 的 class

這邊的const string 很關鍵,字串的值必須與appsettings.json中的StripeSetting段落的組態名稱匹配。

回到我們的Program.cs

builder.Services.Configure<StripeService>(builder.Configuration.GetSection(StripeService.StripeSetting));

我們就可以完全用強型別的方式去指定,我們要從appsettings.json拿取的Section 也就是StripeSetting 這個段落。

回到我們的Controller

一樣從constructor DI注入取得IOptions服務

就可以用_options.Value.XXX,強型別的方式取得我們的組態設定了。

這樣的寫法可重複利用性很高,很適合需要使用httpclient去呼叫API需要帶入Api Key的場合。


Custom Json Configuration

最後想跟大家分享的是Custom Json Configuration,也就是自定義Json檔。

通常我們會使用上這樣的場合可能不多,可能我們想在另一個Json檔案中存放資料;亦或是原先的appsettings.json資料量太多難以管理時想開一個屬於自己的Json檔案,這時候我們就可以使用自定義Json檔。

我在專案檔內加入了MyConfig的json檔案,並且把剛剛的StripeSetting 複製了過來,改了它們的Value 好辨識是從我們新建立的MyConfig.json。

回到我們Program.cs

.Net Core Configuration(組態設定)

來自定義我們的json文檔

builder.Configuration.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true);

第一個參數是我們自定義json的檔名,第二個參數 optional: true 的意思代表該檔案是可選的,並不會因為找不到該文件而發生exception,reloadOnChange: true的意思是當程式在Runtime的時候,只要組態設定改變了程式就會重啟。

我們Controller的code並沒有更動,但是卻已經從MyConfig.json取得組態設訂了,這是因為我們新增了自定義組態的來源,我們的自定義設定有著較高的優先層級,這也是要特別注意的地方!

這次的Configuration分享大概就是這樣,有機會再跟大家分享Secret Manager 或是 Environment 環境變數的操作,倘若有任何問題或想分享的,歡迎留言給我~

Visited 160 times, 1 visit(s) today

Leave A Comment

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