天天看點

解讀ASP.NET 5 & MVC6系列(5):Configuration配置資訊管理基本用法架構設計詳細用法敏感資訊配置(RC版新增功能)自定義配置源配置資訊周遊配置資訊直接轉換為實體類注意事項:同步與推薦

在前面的章節中,我們知道新版的MVC程式抛棄了原來的web.config檔案機制,取而代替的是config.json,今天我們就來深入研究一下配置檔案的相關内容。

新版的配置資訊機制在Microsoft.Framework.ConfigurationModel命名空間下進行了重寫,重寫以後不僅支援XML格式,還支援json、ini、環境變量等。在模闆示例程式中Startup類的構造函數内如,有如下語句:

該語句的作用是将config.json檔案以及環境變量資訊加入到配置資訊容器裡,以便進行讀取。而讀取的時候則可以通過集合索引的形式或Get方法進行讀取,示例如下:

其中,多層級key鍵的讀取,需要在多個層級名稱之間用冒号分割即可,示例如下:

通過上述幾段代碼可以看出,該配置示例并不是全局執行個體,是以要想在别的地方也讀取這些資訊,就需要将該執行個體儲存在一個全局靜态變量上。

新的配置資訊處理機制,在重寫以後,更加輕量級,而且是進行跨平台使用,可以從多個資料源擷取配置資訊,而不必在拘泥于.config檔案,而且甚至可以為不同的環境(開發、測試、生産)設定不同的配置資訊。整個配置機制的各個重要實體見下圖:

解讀ASP.NET 5 & MVC6系列(5):Configuration配置資訊管理基本用法架構設計詳細用法敏感資訊配置(RC版新增功能)自定義配置源配置資訊周遊配置資訊直接轉換為實體類注意事項:同步與推薦

我們來一一講述一下,這些類的具體作用:

<code>IConfiguration</code> - 配置資訊的執行個體接口,該接口上的<code>indexer</code>、<code>Get</code>、<code>TryGet</code>、<code>Set</code>以及其它一些像<code>Reload</code>這樣的方法一起用于擷取基于key/value的配置資訊。

<code>IConfigurationSource</code> - 該接口統一了各個配置源使用時的接口方法,比如<code>TryGet</code>、<code>Set</code>以及最重要的讀取配置資訊的<code>load</code>方法,以便将資訊加載到配置子系統裡。

<code>IConfigurationSourceContainer</code> - 所有配置源資訊的一個容器,該容器使得可以在一個單獨的Configuration執行個體上加載各種配置源的配置資訊。該接口隻有一個<code>Add</code>方法用于添加基于<code>IConfigurationSource</code>的配置源資訊。

<code>Configuration</code> - 該類實作了<code>IConfiguration</code>接口和<code>IConfigurationSourceContainer</code>接口,不儲存基于key/value的所有類型的配置資訊。

<code>ConfigurationExtensions</code> - 擴充方法,用于快速加載配置資訊,如<code>AddCommandLine</code>、<code>AddIniFile</code>等。

在Microsoft.Framework.ConfigurationModel命名空間下,目前有6種不同類型的配置源類型可以使用,分别如下:

<code>MemoryConfigurationSource</code> - 該配置源目前沒有内置的add/load擴充方法(比如<code>AddMemoryConfiguration</code>),但你可以加載key/value類型的集合來實作此目的(如<code>IEnumerable&lt;KeyValuePair&lt;string, string&gt;&gt;</code>類型)。

<code>IniFileConfigurationSource</code> - 該配置源,可以将基于key/value格式的INI檔案配置資訊加載到配置系統中。

<code>CommandLineConfigurationSource</code> - 将程式啟動時的指令行參數資訊加載到配置系統中。

<code>EnvironmentVariablesConfigurationSource</code> - 将作業系統的環境變量資訊加載到配置系統中,在Azure Website中,環境變量可以通過web界面進行設定,管理相當友善。

<code>JsonConfigurationSource</code> - 将json檔案的資訊加載配置系統。

<code>XmlconfigurationSource</code> - 将xml檔案的資訊加載到配置系統。

首先,由于配置系統是多執行個體型的,是以每次使用之前都要先聲明一個示例,代碼如下:

由于在IConfigurationSourceContainer上沒有為MemoryConfigurationSource定義快速加載配置資訊的擴充方法,是以如果想加載這種類型的配置資訊,則需要按照如下形式進行添加:

IniFileConfigurationSource類型的配置資訊可以通過擴充方法進行加載,代碼如下:

其中ini檔案的格式模闆如下:

這裡的[ini-sec]是自定義的配置節名稱,每個配置節下面可以配置多個key/value項。取值方式和基本示例中的一樣,層級之間(本例是配置節和key之間)要用冒号分割,示例如下:

在程式使用k run命名進行時傳入的參數,可以通過該配置源進行讀取,或者你也可以通過<code>AddCommandLine</code>擴充方法手工添加,示例如下:

上述示例中的每個字元串都要是key/value格式,可以使用少于的特殊符号比如$、/等。 針對這些key值,你也可以使用帶有<code>switchMappings</code>參數構造函數的<code>CommandLineConfigurationSource</code>類來映射某些key,<code>switchMappings</code>參數的資料類型和示例如下:

由于目前沒有針對CommandLineConfigurationSource類的擴充方法,是以我們還是需要自己執行個體化該類,并添加到配置容器中,代碼如下:

執行上述代碼以後,在擷取配置值的時候,如下兩個key的值是一樣的:

在映射的時候,新的映射key字元串裡不能包括“/”字元,否則會報異常 同樣的key不能傳入兩次,否則也會報異常 加載配置資訊時,如果有重複key,則後一個key的值會覆寫前一個key的值。 加載CommandLine配置資訊時,如果一個key字元串以-作為字首,那麼就必須利用switchMapping将一個新key映射到舊key上,否則就會出錯。

<code>ironmentVariablesConfigurationSource</code>可以将作業系統的環境變量添加到配置系統中,同時你也可以對這些環境變量進行自定義,比如在VS開發調試的時候,可以在如下界面添加一些key/value:

解讀ASP.NET 5 &amp; MVC6系列(5):Configuration配置資訊管理基本用法架構設計詳細用法敏感資訊配置(RC版新增功能)自定義配置源配置資訊周遊配置資訊直接轉換為實體類注意事項:同步與推薦

取值方式如下:

另外,該配置源也支援Azure環境變量和連接配接字元串,是以你也可以在Azure界面裡設定MSSQL、MYSQL、以及自定義連結字元串等等,但這些連結字元串需要以如下字元串開頭:

MySQL =&gt; <code>MYSQLCONNSTR_</code>

MS SQL =&gt; <code>SQLCONNSTR_</code>

SQL Azure DB =&gt; <code>SQLAZURECONNSTR_</code>

Custom DB =&gt; <code>CUSTOMCONNSTR_</code>

舉例來說,定義一個開發環境的key/value如下:

通過AddEnvironmentVariables()的形式load完資訊以後,我們則可以通過如下方式來通路這項資訊:

也就是說,在Azure裡,環境變量的key會轉換成Data:自定義辨別符:ConnectionString這樣的格式。如果你的key不是自定義key(以<code>CUSTOMCONNSTR_</code>開頭)的話,你可以用如下方式擷取連接配接字元串的provider名稱,示例如下:

<code>EnvironmentVariablesConfigurationSource</code>另外還提供一種字首過濾的方式加載部分資訊,比如:

這樣,再擷取資訊的時候,key值裡的Data:就可以省略了,示例如下:

在文章的開頭,我們看到了json配置檔案的加載,加載該檔案隻需要使用<code>.AddJsonFile("test.json")</code>擴充方法即可,但不要忘記,要先在project.json的dependencies裡引用Microsoft.Framework.ConfigurationModel.Json程式集才行。

比如,如果你的config.json檔案内容如下:

那你就可以利用如下方式來通路連結字元串:

<code>XmlconfigurationSource</code>配置源和JsonConfigurationSource配置源類似,首先引用Microsoft.Framework.ConfigurationModel.Xml程式集,然後調用<code>.AddXmlFile("test.xml")</code>。

如果你的配置檔案test.xml的内容如下:

擷取形式,則稍有有些差別(會忽略根節點root):

但是要注意,通用的key不能重複聲明,下面的檔案在讀取的時候就會出錯。

在RC版釋出以後,微軟又新增了一種敏感資訊配置實作,程式集為<code>Microsoft.Framework.ConfigurationModel.UserSecrets</code>,通過該程式集的管理,我們可以将敏感的配置資訊放在計算機的特殊目錄下的<code>secrets.json</code>檔案,其目錄定義規則如下:

我們來舉例操作一下,首先,右鍵解決方案選擇<code>Manage User Secret</code>,VS會自動給該程式建立一個<code>applicationId</code>,并保持在·project.json·檔案中,示例如下:

接着會自動打開<code>%APPDATA%\Microsoft\UserSecrets\aspnet5-WebDemo01-20150430014447\secrets.json</code>檔案,我們輸入一個示例配置:

然後,我們在project.json檔案裡引用了上述程式集,再通過配置檔案的統一方式進行注冊,代碼如下:

然後就可以想普通的調用方法一下調用了,示例如下:

通過這種方式,我們就可以将生産環境的配置資訊放在隐私的位置了。

通過以上示例以及檢視其架構設計機制,我們可以發現,其實我們還可以自定義自己的配置源,比如我想從資料庫中讀取響應的配置資訊,那我們隻要定義一個DBConfigurationSource,并繼承于ConfigurationSource即可,實作響應的Load重載即可。

如果你不把資料儲存在Data屬性裡,那麼你還要實作如下幾個重載,以便從自己的私有資料集合裡擷取響應的值,比如從緩存中擷取,示例如下:

實作完上述類以後,再為自己建立一個擴充方法用于添加DB配置資訊,代碼如下:

就可以通過.AddDBConfiguration()來添加DB配置源了。

注意,DB配置源需要使用資料庫連接配接字元串,這一點需要注意(擷取可以先從json配置檔案擷取連接配接字元串,然後再添加該配置源)。

在預設的配置源實作中,所有的類都繼承于ConfigurationSource,并且将資訊資料儲存在Data屬性中,是以如果要周遊這些資料,則需要将其轉換為ConfigurationSource類型才能使用,示例代碼如下:

在<code>IServiceCollection</code>接口上還有一個擴充方法<code>.Configure&lt;T&gt;</code>可以将類型<code>IConfiguration</code>的資料轉換為一個實體類,該擴充方法的定義如下:

舉個例子,如果我們定義如下一個實體:

然後在<code>config.json</code>裡定義一個相同結構的配置資訊,示例如下:

那麼通過在<code>Startup</code>的構造函數将配置資訊加載以後,我們就可以将該資訊指派給<code>AppSettings</code>執行個體,代碼如下:

用的時候,使用<code>ApplicationServices</code>的<code>GetRequiredService</code>方法即可,示例如下:

在配置資訊裡,所有的key都是不區分大小寫的,即key和KEY是一樣的。

如果多個配置源有重複的key,則以後最後添加的配置源中的key所對應的值為準。

<code>IConfiguration</code>下的<code>GetSubKeys</code>和<code>GetSubKey</code>可以擷取某個層級(或以某個層級開頭的)的所有key清單。

由于<code>Configuration</code>是多執行個體的,是以按照示例中的代碼,該執行個體在<code>Startup</code>裡初始化以後,其它類就無法通路了,是以如果要做全局性的通路,最好在初始化之後将其儲存到一個靜态變量中。