大多數應用都離不開配置,本章將介紹ASP.NET Core中常見的幾種配置方式及系統內部實現的機制。(ASP.NET Core 系列目錄) 說到配置,第一印象可能就是“.config”類型的xml文件或者“.ini”類型的ini文件,在ASP.NET Core 中,常用的配置文件類型為JSON。比如 ...
大多數應用都離不開配置,本章將介紹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