簡介
ASP.NET Core 的配置系統旨在提供統一、靈活的方式來讀取應用程序設置。它具備以下特點:
- 支持多種配置源:JSON、XML、INI、環境變量、命令行、內存、用户機密、數據庫、自定義等;
- 層級合併與覆蓋:後添加的配置源會覆蓋前面的同名鍵;
- 鍵名稱統一:默認使用 “冒號”分隔的層級鍵(如
Logging:LogLevel:Default); - 與
DI整合:通過IConfiguration及IOptions<T>注入到服務中; - 動態重載:部分配置源(如
JSON文件)支持文件更改時自動刷新。
整個流程通常是在程序啓動時通過 ConfigurationBuilder 構建一個 IConfigurationRoot,並將其註冊到依賴注入容器。
配置系統架構演進
配置系統演進:
.NET Framework時代:基於XML的app.config/web.config,通過ConfigurationManager訪問.NET Core+時代:靈活的統一配置模型,支持多種配置源和格式
核心特性
-
多源配置:
- 支持多種配置提供程序(
Providers),如JSON、XML、INI、環境變量、命令行、Azure Key Vault等。 - 配置按添加順序合併,後添加的提供程序覆蓋前面的值。
- 支持多種配置提供程序(
-
類型安全綁定:
- 使用
Bind方法或Options Pattern將配置映射到C#對象。 - 示例:
services.Configure<MySettings>(configuration.GetSection("MySettings"))。
- 使用
-
熱加載(
Hot Reload):- 支持文件更改時自動重新加載配置(如
appsettings.json)。 - 示例:
AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)。
- 支持文件更改時自動重新加載配置(如
-
環境特定配置:
- 支持基於環境的配置文件,如
appsettings.Development.json。 - 示例:
AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)。
- 支持基於環境的配置文件,如
-
依賴注入集成:
- 通過
IOptions<T>、IOptionsSnapshot<T>或IOptionsMonitor<T>注入配置。 - 示例:
services.AddOptions<MySettings>()。
- 通過
-
層次結構支持:
- 支持嵌套配置(如
JSON對象),通過 : 分隔符訪問。 - 示例:
configuration["Database:ConnectionString"]。
- 支持嵌套配置(如
-
擴展性:
- 支持自定義配置提供程序。
- 與
Azure Key Vault、Consul等集成。
-
安全性:
- 支持從
Azure Key Vault或環境變量加載敏感數據(如密碼、API密鑰)。
- 支持從
核心接口與類
-
IConfiguration- 只讀接口,表示配置鍵值對集合。
- 通過索引器
configuration["Section:Key"]訪問。
-
IConfigurationRoot(繼承自IConfiguration)- 代表已構建完成的配置根,可調用
Reload()觸發重新加載。
- 代表已構建完成的配置根,可調用
-
IConfigurationBuilder- 用於逐步添加各類配置源(
Providers),最終通過Build()生成IConfigurationRoot。
- 用於逐步添加各類配置源(
-
IConfigurationProvider- 配置提供者接口,負責從具體源讀取鍵值並加載到內存;
-
IConfigurationSource- 配置提供者的“工廠”,負責創建對應的
IConfigurationProvider。
- 配置提供者的“工廠”,負責創建對應的
在 ASP.NET Core 中,WebApplication.CreateBuilder(args) 會自動創建並添加常見配置源,然後將構建的 IConfiguration 註冊到服務容器中。
配置提供程序 (Providers)
JSON:.AddJsonFile("appsettings.json")- 環境變量:
.AddEnvironmentVariables() - 命令行參數:
.AddCommandLine(args) Azure Key Vault:.AddAzureKeyVault()- 用户機密 (開發環境):
.AddUserSecrets<Program>()
內置配置源
appsettings.json / appsettings.{Environment}.json
// appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning"
}
},
"ConnectionStrings": {
"Default": "Server=.;Database=MyApp;..."
}
}
- 默認會加載
appsettings.json,再加載appsettings.Development.json(根據ASPNETCORE_ENVIRONMENT環境變量); JSON文件支持層級結構,且可設置reloadOnChange: true以監控文件變動。
環境變量
- 讀取系統環境變量,鍵名以“__”(雙下劃線)代表層級分隔,例如
Logging__LogLevel__Default=Debug; - 環境變量優先級高於
JSON。
命令行參數
dotnet run --Logging:LogLevel:Default=Trace --MyOption:Sub=Value
- 命令行參數形式必須是 --鍵=值,覆蓋所有前面加載的源。
其他常見源
INI文件:builder.AddIniFile("config.ini");XML文件:builder.AddXmlFile("config.xml");- 內存字典:適合單元測試或運行時動態添加:
builder.AddInMemoryCollection(new Dictionary<string,string>{
["MyKey"]="MyValue"
});
配置優先級(從高到低)
- 命令行參數
- 環境變量
- 用户機密 (開發)
appsettings.{Environment}.jsonappsettings.json
基礎使用
// 獲取配置值
string connectionString = configuration["ConnectionStrings:DefaultConnection"];
string apiKey = configuration["ApiKey"];
int timeout = configuration.GetValue<int>("Timeout", 30); // 獲取值,帶默認值
// 獲取配置節
IConfigurationSection databaseSection = configuration.GetSection("Database");
string server = databaseSection["Server"];
string database = databaseSection["Name"];
構建與註冊
在 Program.cs(最簡版)中:
var builder = WebApplication.CreateBuilder(args);
// builder.Configuration 已經包含:
// 1. appsettings.json
// 2. appsettings.{Env}.json
// 3. 環境變量
// 4. 命令行
// 可繼續添加自定義源
builder.Configuration
.AddJsonFile("custom.json", optional:true, reloadOnChange:true)
.AddUserSecrets<Program>();
// 註冊 Options
builder.Services.Configure<MySettings>(builder.Configuration.GetSection("MySettings"));
var app = builder.Build();
強類型綁定(Options 模式)
直接從 IConfiguration 獲取字符串較為零散,推薦使用 Options 模式將配置映射為 POCO 對象,並通過 DI 獲取。
定義配置對象
public class MySettings
{
public string Url { get; set; }
public int RetryCount { get; set; }
public NestedSettings Nested { get; set; }
}
public class NestedSettings
{
public bool Enabled { get; set; }
}
對應 appsettings.json:
"MySettings": {
"Url": "https://api.example.com",
"RetryCount": 3,
"Nested": {
"Enabled": true
}
}
在 Program.cs 中綁定
builder.Services
.AddOptions<MySettings>()
.Bind(builder.Configuration.GetSection("MySettings"))
.ValidateDataAnnotations() // 可選:啓用數據註解驗證
.Validate(s => s.RetryCount >= 0, "RetryCount must be non-negative");
在業務中注入使用
public class MyService
{
private readonly MySettings _settings;
public MyService(IOptions<MySettings> opts)
{
_settings = opts.Value;
}
public void Run() {
Console.WriteLine(_settings.Url);
}
}
也可注入 IOptionsMonitor<T>(支持變更監聽)或 IOptionsSnapshot<T>(每次請求新的快照,僅限 Scoped 服務)。
動態重載與變更監聽
對於支持 reloadOnChange: true 的配置源(如 JSON 文件、環境變量不支持文件監控),IOptionsMonitor<T> 可感知配置變更並觸發回調:
services.AddOptions<MySettings>()
.Bind(config.GetSection("MySettings"))
.ValidateDataAnnotations();
services.AddSingleton<IHostedService, MonitorService>();
public class MonitorService : BackgroundService
{
private readonly IOptionsMonitor<MySettings> _monitor;
public MonitorService(IOptionsMonitor<MySettings> monitor)
=> _monitor = monitor;
protected override Task ExecuteAsync(CancellationToken ct)
{
_monitor.OnChange(s =>
Console.WriteLine($"New URL: {s.Url}")
);
return Task.CompletedTask;
}
}