很久之前,在玩Docker的時候順便扒了扒,最近,終於下定決心花了些時間整理並成文,希望能夠給大家一些幫助。
目錄
-
.NET Core中的配置
-
ASP.NET Core中的配置
-
扒一扒環境變量提供程序
-
為什么是“__”?
-
“__”如何變成了“:”?
-
數據庫連接字符串的配置的特殊規則
-
最后
前言
.NET Core的配置提高程序非常強大和靈活,支持從各種配置源讀取鍵值對:
· 命令行參數
· 目錄文件(.json、xml、ini)
· 環境變量
· 內存中的對象
· Azure Key Vault
本篇我們側重於扒一扒.NET Core的環境配置程序,了解其執行機制和特殊規則以及原理。因為通過環境變量來配置在很多場景都非常有用,尤其是在Docker環境之中。具體使用大家可以看看下面給出的截圖和配置示例。
.NET Core中的配置
在.NET Core中,我們通常這么玩:
1. 添加依賴:
<PackageReferenceInclude="Microsoft.Extensions.Configuration"Version="2.2.0" />
<PackageReferenceInclude="Microsoft.Extensions.Configuration.CommandLine"Version="2.2.0" />
<PackageReferenceInclude="Microsoft.Extensions.Configuration.EnvironmentVariables"Version="2.2.0" />
2. 添加配置代碼
privatestaticvoid Main(string[] args)
{
var config = newConfigurationBuilder()
//支持命令行參數
.AddCommandLine(args)
//支持環境變量
.AddEnvironmentVariables()
.Build();
}
ASP.NET Core中的配置
因為在ASP.NET Core中,包“Microsoft.AspNetCore.App”已經包含了對“Microsoft.Extensions.Configuration”等包的依賴,因此在ASP.NET Core的應用程序中,通常我們會用以下代碼來啟用配置提供程序:

有時候我們也會使用下面代碼來自定義配置:

對於第一種寫法,我們可以通過查看源碼了解其具體機制:

扒一扒環境變量提供程序
接下來我們重點扒一扒環境變量提供程序,環境變量提供程序在容器這塊應用極廣,也極為方便,比如設置日志的輸出級別:
docker run --nameaspnetcore_sample --rm -it -p 8000:80 -e 'Logging__LogLevel__Default=Debug' microsoft/dotnet-samples:aspnetapp

docker run --nameaspnetcore_sample1 --rm -it -p 8000:80 microsoft/dotnet-samples:aspnetapp

通過上面的對比,我們可以第一個命令通過設置了環境變量“Logging__LogLevel__Default=Debug”輸出了調試日志。而且從上面代碼來看,環境變量的配置會覆蓋文件配置:

那么“Logging__LogLevel__Default”對應什么樣的文件配置呢?如下所示:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
如上所示,這個配置我們在appsettings.json中能夠找到。不過很奇怪的是,為什么通過環境變量配置會變成“Logging__LogLevel__Default"呢(注意中間是兩個下划線)?
為什么是“__”?
我們繼續來扒一扒。繼續看源碼:
首先我們查看AddEnvironmentVariables的代碼:

順藤摸瓜找到了
EnvironmentVariablesConfigurationSource:

最終扒開了EnvironmentVariablesConfigurationProvider的代碼,找到了關鍵:

我們來挨個解析下重點。
“__”如何變成了“:”?
這個“__”在我們使用的時候,怎么變成“:”的呢?比如我們使用的時候都是這么玩的:
appConfiguration["RedisCache:ConnectionString"]
關鍵代碼如下所示:
private static stringNormalizeKey(string key)
{
return key.Replace("__",ConfigurationPath.KeyDelimiter);
}
數據庫連接字符串的配置的特殊規則
在上圖我們看到了一些特殊的判斷,也就是扒出了數據庫連接字符串的幾個特殊名稱前綴,這是怎么回事呢?這里我們補充說明一下:
針對連接字符串,.NET Core提供了一些特殊的處理規則。主要支持以下數據庫:
| 連接字符串前綴 |
提供程序 |
| CUSTOMCONNSTR_ |
自定義提供程序 |
| MYSQLCONNSTR_ |
MySQL |
| SQLAZURECONNSTR_ |
Azure SQL 數據庫 |
| SQLCONNSTR_ |
SQL Server |
當發現有以上前綴的環境變量時,會進行一些特殊處理:根據前綴在ConnectionStrings節添加對應的鍵值對,並且添加數據庫提供程序的配置,如下所示:
| 環境變量鍵 |
轉換的配置鍵 |
提供程序配置條目 |
| CUSTOMCONNSTR_<KEY> |
ConnectionStrings:<KEY> |
配置條目未創建。 |
| MYSQLCONNSTR_<KEY> |
ConnectionStrings:<KEY> |
鍵: ConnectionStrings:<KEY>_ProviderName: |
| SQLAZURECONNSTR_<KEY> |
ConnectionStrings:<KEY> |
鍵: ConnectionStrings:<KEY>_ProviderName: |
| SQLCONNSTR_<KEY> |
ConnectionStrings:<KEY> |
鍵: ConnectionStrings:<KEY>_ProviderName: |
如果說了這么多你還不太明白,簡單的來講,對於常用的數據庫連接字符串,.NET環境變量提供程序提供了內置的簡寫進行配置,比如在Docker參數中我們可以這么配置:
-e ‘SQLCONNSTR_Default=Server= 192.168.1.11;Database=test; User ID=dev;Password=dev;’
如上所示,其中Default對應配置文件的示例如下圖所示:

這樣說是否明白了呢?如上所示,主要支持MySQL、Azure SQL 數據庫和SQL Server。
最后
我們再來看看環境變量最終是如何變成配置路徑,如以下代碼:

至此,整個環境變量提供程序均已扒完,這次就說到這里。
.NET Core的配置非常靈活和強大,想了解更多,大家可以直接通過官網學習:
只是結合代碼,能夠更易於我們理解以及使用。
