ASP.NET Core中的配置項能夠經過命令行、環境變量、json/xml/ini配置文件來提供。json
Web應用在生成主機時會調用CreateDefaultBuilder方法,這個方法按照下面的順序添加各類配置提供程序:數據結構
對於同一配置,後面加載的配置提供程序會覆蓋前面加載的內容,因此配置的默認優先級從低到高依次爲:文件 -> 環境變量 -> 命令行。app
配置 API 可以經過在配置鍵中使用分隔符來展平分層數據以保持分層配置數據。
好比,這樣的json文件:ide
{ "section0": { "key0": "value", "key1": "value" }, "section1": { "key0": "value", "key1": "value" } }
配置提供程序加載時,將使用冒號 (😃 展平節和鍵,以這樣的方式建立惟一鍵以保持配置源的原始分層數據結構。ui
section0:key0 section0:key1 section1:key0 section1:key1
配置鍵採用如下約定:this
配置值的約定:編碼
能夠經過ConfigureHostConfiguration和ConfigureAppConfiguration方法來指定配置提供程序或者設置提供程序的優先級。
若是不須要CreateDefaultBuilder默認添加的配置提供提供程序,能夠直接刪除spa
.ConfigureAppConfiguration((hostingContext, config) => { config.Sources.Clear(); })
在ConfigurationBuilder 的實例上調用 AddCommandLine 擴展方法能夠激活命令行配置,不過CreateDefaultBuilder已經自動調用了AddCommandLine,而且命令行配置的優先級最高。若要添加其餘配置提供程序並保持可以用命令行參數替代這些提供程序的配置,能夠在ConfigureAppConfiguration中添加完其餘提供程序後,再調用一次AddCommandLine。命令行
.ConfigureAppConfiguration((hostingContext, config) => { // Call other providers here config.AddCommandLine(args); })
命令行配置的設置方式爲:code
dotnet run CommandLineKey=CommandLineValue
這種設置方法使用了等號(=),也能夠用--或/做爲前綴,並空格代替等號,下面的寫法都是合理的:
dotnet run --CommandLineKey2=value2 dotnet run --CommandLineKey2 value2 dotnet run /CommandLineKey3=value3 dotnet run /CommandLineKey3 value3
在ConfigurationBuilder 的實例上調用 AddEnvironmentVariables 擴展方法能夠激活環境變量配置,CreateDefaultBuilder也已經默認啓用了環境變量配置提供程序。
AddEnvironmentVariables方法還有一個重載支持加載指定前綴的環境變量。
好比
.AddEnvironmentVariables("CUSTOM_")
會只加載前綴爲CUSTOM_的環境變量。
環境變量的設置方法:
以Json文件爲例(INI、XML文件相似):
.ConfigureAppConfiguration((hostingContext, config) => { config.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true); .AddJsonFile($"MyConfig.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); })
以這種順序添加,後面MyConfig.{env.EnvironmentName}.json中的配置會覆蓋MyConfig.json中的同名配置。
從配置中提取一個具備指定鍵的值,並將它轉換爲指定的類型
var number = Configuration.GetValue<int>("NumberKey", 99);
會返回具備指定子節鍵的配置子節
section1 = configuration.GetSection("section1");
對於GetSection的結果,可使用GetValue
var starship = _config.GetSection("starship").Get<Starship>();
{ "starship": { "name": "USS Enterprise", "registry": "NCC-1701", "class": "Constitution", "length": 304.8, "commissioned": false, "Array": [ "12", "23", "d3" ], "ShipLog": { "ID": "1" } } ... }
public class Starship { public string Name { get; set; } public string Registry { get; set; } public string Class { get; set; } public decimal Length { get; set; } public bool Commissioned { get; set; } public ShipLog ShipLog { get; set; } public string[] Array { get; set; } } public class ShipLog { public string ID { get; set; } }
除了上述配置提供程序,還能夠自定義配置數據源,好比能夠統一從配置中心獲取配置。
要自定義配置源,須要實現IConfigurationSource和IConfigurationProvider。
實現IConfigurationSource:
class MyConfigurationSource : IConfigurationSource { public IConfigurationProvider Build(IConfigurationBuilder builder) { return new MyConfigurationProvider(); } }
實現IConfigurationProvider,具體方式能夠經過繼承ConfigurationProvider,而後重寫它的虛方法。下面的示例重寫了Load方法,在這裏能夠自行編碼獲取配置、設置到this.Data,Data是一個鍵和值類型都是string的字典,用於存儲配置。還用了一個定時器來模擬配置的變動,在發生配置變動時,觸發base.OnReload();
class MyConfigurationProvider : ConfigurationProvider { Timer timer; public MyConfigurationProvider() : base() { timer = new Timer(); timer.Elapsed += (a, b) => Load(true); timer.Interval = 3000; timer.Start(); } public override void Load() { //加載數據 Load(false); } void Load(bool reload) { this.Data["lastTime"] = DateTime.Now.ToString(); if (reload) { base.OnReload(); } } }
使用的時候:builder.Add(new MyConfigurationSource());
但這種方法會暴露具體的實現,能夠封裝爲擴展方法。若是把這個擴展類的命名空間指定爲Microsoft.Extensions.Configuration,這樣在分發到第三方後,就能夠直接使用,而沒必要using程序集的命名空間,而前面的實現類默認爲internal,第三方沒法訪問到,實現了整個類庫只暴露出一個擴展方法的效果。
namespace Microsoft.Extensions.Configuration { public static class MyConfigurationBuilderExtensions { public static IConfigurationBuilder AddMyConfiguration(this IConfigurationBuilder builder) { builder.Add(new MyConfigurationSource()); return builder; } } }
監聽配置變動的方法:
builder.AddMyConfiguration(); var configRoot = builder.Build(); ChangeToken.OnChange(() => configRoot.GetReloadToken(), () => { //監聽到配置變動後的處理代碼 });