1. 程式人生 > >ASP.NET Core 2.2 : 二十二. 多樣性的配置方式

ASP.NET Core 2.2 : 二十二. 多樣性的配置方式

    大多數應用都離不開配置,本章將介紹ASP.NET Core中常見的幾種配置方式及系統內部實現的機制。(ASP.NET Core 系列目錄)

    說到配置,第一印象可能就是“.config”型別的xml檔案或者“.ini”型別的ini檔案,在ASP.NET Core 中,常用的配置檔案型別為JSON。比如專案根目錄中的appsettings.json和appsettings.Development.json兩個檔案。實際上,ASP.NET Core支援多種配置方式,除了採用JSON檔案的方式外,還支援記憶體、命令列等方式。

一、檔案方式

這是最常見的方式,ASP.NET Core支援多種格式的配置檔案,例如常見的JSON、XML、INI等格式的檔案。

首先看一下專案預設建立的配置檔案appsettings.json,其內容預設如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

這個檔案會在系統啟動的時候自動被載入(載入發生在Program檔案的CreateWebHostBuilder方法中,下一節會詳細說明),預設內容主要是對Log的配置。

舉個例子,需要在配置檔案中設定應用的主題,例如顏色風格等。向檔案末尾新增如下內容:

 "Theme": {
    "Name": "Blue",
    "Color": "#0921DC"
  }

用通過這樣的程式碼設定了系統的主題和對應的色值。那麼這個值是如何被獲取並使用的呢?以預設的HomeController為例,新建一個名為“GetConfiguration”的Action來演示Configuration值的獲取。程式碼如下:

privatereadonlyIConfiguration _configuration;
publicHomeController(IConfiguration configuration) { _configuration = configuration; } publicContentResult GetConfiguration() { returnnewContentResult() { Content = $"Theme Name:{ _configuration["Theme:Name"] },Color:{_configuration["Theme:Color"]}"}; }

  在構造方法中通過依賴注入的方式獲取到了一個IConfiguration,並在Action中通過這個IConfiguration獲取到了appsettings.json中設定的值。可以看出,在獲取值的時候,是通過“:”符號來體現JSON的層級關係體現的。例如獲取“Color”的值,對應的表示式為“_configuration["Theme:Color"]”。這是因為整個JSON會被處理為一個個的Key-Value的格式,本例的“Theme”的兩個值會被分解為如下格式:

Key

Value

Theme:Name

Blue

Theme:Color

#0921DC

這裡有兩個說明,第一,“Key”不區分大小寫,即寫為“theme:color”也是等效的;第二,約定“Value”值是字串格式。

除了上例中的獲取方式,還可以通過GetValue方法獲取。

_configuration.GetValue<string>("Theme:Color","#000000")

含義是將獲取到的值轉換為string型別,如果獲取失敗則返回預設值“#000000”。

本例演示了系統預設的appsettings.json檔案中的內容被自動載入,那麼如何將自定義的JSON檔案中的內容應用到系統的配置中去呢?

新建一個名為“Theme.json”的檔案,同樣再預設一個紅色主題,程式碼如下:

{
  "Theme": {
    "Name": "Red",
    "Color": "#FF4500"
  }
}

由於這個自定義的“Theme.json”不會被自動載入,需要手動將其新增到系統的配置中去,在講應用系統的啟動的時候說過,配置是在Program檔案的CreateDefaultBuilder方法中被載入的,可以在其之後繼續通過ConfigureAppConfiguration方法繼續設定。例如如下程式碼:

publicstaticIWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext,config)=> {
        config.SetBasePath(Directory.GetCurrentDirectory());
        varpath = Path.Combine(Directory.GetCurrentDirectory(), "Theme.json");
        config.AddJsonFile(path, optional: false, reloadOnChange: true);
    })
    .UseStartup<Startup>();
}

首先通過SetBasePath方法設定了基路徑,然後通過AddJsonFile方法新增“Theme.json”檔案,這個方法有3個引數,第一個是“Theme.json”所在的位置,第二個設定此檔案是否可選,第三個設定當此檔案被修改後,是否自動重新載入該檔案。

再次訪問home/GetConfiguration,返回的結果如下:

Theme Name:Red,Color:#FF4500

這是因為後新增的Theme.json檔案中的Theme值覆蓋了appsettings.json檔案中的Theme值。這涉及到各種配置設定方式的優先順序問題,在下一節會講。

說完了將JSON格式的檔案用作配置的例子,再看看如何採用INI格式的。新建一個名為Theme.ini的檔案,為了不覆蓋之前設定的Theme,本例將Theme改為了ThemeGreen。

[ThemeGreen]
Name=Green
Color=#76EE00

通過ConfigureAppConfiguration方法將這個INI檔案新增到配置中去。

var pathIni = Path.Combine(Directory.GetCurrentDirectory(), "Theme.ini");
config.AddIniFile(pathIni, optional: false, reloadOnChange: true);

修改Action中讀取配置的Key,將對應的將Theme改為ThemeGreen:

publicContentResult GetConfiguration()
{
    returnnewContentResult() { Content = $"Theme Name:{ _configuration["ThemeGreen:Name"] },Color:{_configuration.GetValue<string>("ThemeGreen:Color", "#000000")}"};
}

再次訪問home/GetConfiguration,返回的結果如下:

Theme Name:Green,Color:#76EE00

上面介紹了JSON和INI兩種格式的檔案的應用,除了二者檔案格式的不同以及被新增到配置時採用的方法不同(分別採用了AddJsonFile和AddIniFile方法),在其他環節二者的使用方式均是一樣的。同理,對於XML格式的檔案,有一個對應的AddXmlFile方法,其他環節和JSON、INI檔案的應用也是一樣的,此處就不再舉例描述。

二、目錄檔案

除了上一節利用JSON、INI和XML這樣常用的檔案格式外,還可以將指定目錄和檔案作為配置的資料來源。

例如現在有個資料夾s,其下面有1.txt和2.txt兩個檔案,檔案內容分別是s1和s2,如下圖1

 

圖1

可以將這一的目錄和檔案作為配置的資料來源,同樣只需要在ConfigureAppConfiguration方法中新增即可,見如下程式碼:

var pathFile = Path.Combine(Directory.GetCurrentDirectory(), "s");
config.AddKeyPerFile(directoryPath: pathFile, optional: true);

通過一個Action測試一下:

publicContentResult GetFileConfiguration()
{
     returnnewContentResult() { Content = $"1.txt:{_configuration["1.txt"]}, 2.txt:{_configuration["2.txt"]}"};
}

返回結果為:

1.txt:s1,2.txt:s2

可見這樣的方法是將s資料夾下的兩個檔案的檔名作為了Key,檔案內容作為Value。

三、命令列

通過命令列啟動應用的時候,可以在命令列中通過新增Key-Value的方式作為配置的資料來源,例如執行如下命令啟動應用:

dotnet run key1=value1 key2=value2

訪問定義好的如下Action:

publicContentResult GetCommandConfiguration()
{
    returnnewContentResult() { Content = $"key1:{_configuration["key1"]}, key2:{_configuration["key2"]}"};
}

返回結果為:

key1:value1,key2:value2

這是由於在預設的WebHost.CreateDefaultBuilder(args)方法中添加了對命令列引數的呼叫,如果需要在ConfigureAppConfiguration方法中繼續新增,只需要在該方法中南呼叫config.AddCommandLine(args)方法即可。

四、環境變數

在WebHost.CreateDefaultBuilder(args)方法中,除了會載入命令列引數,還會載入環境變數中的資料。此處的環境變數包括系統的環境變數,例如下圖2

 

圖2

環境變數中的“變數”和“值”會被讀取為配置的Key和Value。

除了讀取系統的環境變數,也可以在專案的屬性中新增,例如在專案的屬性中新增,例如下圖3:

 

圖3

除了熟悉的名為ASPNETCORE_ENVIRONMENT的環境變數,又在這裡添加了一個Key為TestKey,Value為TestValue的環境變數。

新增一個Action測試一下:

publicContentResult GetEnvironmentVariables()
{
    returnnewContentResult() { Content = $"TestKey:{_configuration["TestKey"]}, OS:{_configuration["OS"]}"};
}

分別讀取了圖2和圖3中的兩個環境變數,訪問這個Action,返回結果為:

TestKey:TestValue,OS:Windows_NT 

 五、記憶體物件

以上的例子都是將一些外部的資料來源讀取並轉換成了配置中的Key-Value格式,那麼是否可以直接在應用中通過程式碼方式建立一些Key-Value值並加入到配置中去呢?這當然是可以的。常見的就是Dictionary了,新建一個Dictionary程式碼如下:

public static readonly Dictionary<string, string> dict = newDictionary<string, string> { { "ThemeName", "Purple"},{"ThemeColor", "#7D26CD"} };

在ConfigureAppConfiguration方法中將其加入到配置中去:

config.AddInMemoryCollection(dict);

新建一個Action進行測試:

publicContentResult GetMemoryConfiguration()
{
     returnnewContentResult() { Content = "ThemeName:{_configuration["ThemeName"]}, ThemeColor:{_configuration["ThemeColor"]}"};
}

返回結果為:

ThemeName:Purple,ThemeColor:#7D26CD

 

 

&n