IConfigurationBuilder.AddXxx()不直接接受自定义路径,因其内置方法依赖IFileProvider和FileConfigurationProvider,仅支持物理文件或嵌入资源;需自定义ConfigurationProvider子类并重写Load()方法,用冒号分隔的键存入IDictionary,再通过扩展方法注册。
为什么 IConfigurationBuilder.AddXxx() 不直接接受自定义文件路径
因为
的内置方法(如
、
)底层依赖
和
,它们默认只处理物理文件系统或嵌入资源。若想加载非标准位置(如数据库、HTTP API、加密 ZIP 内的 config.json),不能靠改参数绕过,必须实现自己的
子类。
如何写一个最简可用的自定义 ConfigurationProvider
核心是继承
并重写
方法,把数据转成
格式(键用冒号分隔,如
)。
不要在构造函数里加载数据,
才是唯一被调用的入口
务必调用
初始化基类字段
若需热重载(如监听文件变化),还需实现
并重写
示例:从字符串 JSON 加载
怎样注册自定义 provider 到 IConfigurationBuilder
不能直接用
传实例(会丢失生命周期管理),应封装为扩展方法,内部调用
。
C知道
CSDN推出的一款AI技术问答工具
下载
扩展方法签名必须是
若 provider 依赖服务(如
),需通过
注册,并在 provider 构造中接收
或
注意加载顺序:自定义 provider 在
后注册,其值会覆盖前面同名 key
示例注册方式:
常见踩坑点:Key 命名与层级解析不一致
配置系统对 key 的解析规则和 JSON 对象结构不是 1:1 映射。例如
} 会被展开为
,但如果你手动拼字典时用了
(点号而非冒号),就查不到。
必须用英文冒号
分隔层级,不能用点、下划线或斜杠
数组支持有限:JSON 中
会被转成
、
,但反向绑定到
时可能失败,建议避免在自定义源中暴露数组结构
空值处理:字典中存
值会导致
绑定失败,应存空字符串
或跳过该 key
复杂嵌套或动态 schema 的场景,优先考虑用
+ 自定义 binder,而不是硬塞进 flat 字典。
IConfigurationBuilderAddJsonFile()AddXmlFile()IFileProviderFileConfigurationProviderConfigurationProviderConfigurationProviderLoad()IDictionary"ConnectionStrings:Default"Load()Data = new Dictionary(StringComparer.OrdinalIgnoreCase) IChangeTokenGetReloadToken()public class JsonStringConfigurationProvider : ConfigurationProvider
{
private readonly string _json;
public JsonStringConfigurationProvider(string json) => _json = json ?? throw new ArgumentNullException(nameof(json));
public override void Load()
{
Data = JsonSerializer.Deserialize>(_json)
?? new Dictionary(StringComparer.OrdinalIgnoreCase);
}
} AddProvider()builder.Add(new YourProvider())this IConfigurationBuilder builderHttpClientbuilder.ServicesIOptionsMonitorIServiceProviderAddJsonFile()public static class ConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddJsonString(this IConfigurationBuilder builder, string json)
{
return builder.Add(new JsonStringConfigurationProvider(json));
}
}
// 使用
var config = new ConfigurationBuilder()
.AddJsonString("{\"App:Version\":\"1.2.0\"}")
.Build();{"Logging": {"LogLevel": {"Default": "Information"}}Logging:LogLevel:Default = "Information""Logging.LogLevel.Default":["a","b"]Array:0=aArray:1=bListnullConfigurationBinder""IOptions