简介
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
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。
命令行参数
shell
dotnet run --Logging:LogLevel:Default=Trace --MyOption:Sub=Value
- 命令行参数形式必须是 --键=值,覆盖所有前面加载的源。
其他常见源
-
INI文件:builder.AddIniFile("config.ini"); -
XML文件:builder.AddXmlFile("config.xml"); -
内存字典:适合单元测试或运行时动态添加:
csharp
builder.AddInMemoryCollection(new Dictionary<string,string>{
["MyKey"]="MyValue"
});
配置优先级(从高到低)
-
命令行参数
-
环境变量
-
用户机密 (开发)
-
appsettings.{Environment}.json -
appsettings.json
基础使用
csharp
// 获取配置值
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(最简版)中:
csharp
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 获取。
定义配置对象
csharp
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:
json
"MySettings": {
"Url": "https://api.example.com",
"RetryCount": 3,
"Nested": {
"Enabled": true
}
}
在 Program.cs 中绑定
csharp
builder.Services
.AddOptions<MySettings>()
.Bind(builder.Configuration.GetSection("MySettings"))
.ValidateDataAnnotations() // 可选:启用数据注解验证
.Validate(s => s.RetryCount >= 0, "RetryCount must be non-negative");
在业务中注入使用
csharp
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> 可感知配置变更并触发回调:
csharp
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;
}
}