ICfgRoot 是配置根接口,提供配置读写的核心功能。
public interface ICfgRoot : IDisposable, IAsyncDisposable
{
// 读取操作
string? Get(string key);
T? Get<T>(string key);
bool Exists(string key);
ICfgSection GetSection(string key);
IEnumerable<string> GetChildKeys();
// 写入操作
void Set(string key, string? value, int? targetLevel = null);
void Remove(string key, int? targetLevel = null);
Task SaveAsync(int? targetLevel = null, CancellationToken cancellationToken = default);
// 批量操作
IReadOnlyDictionary<string, string?> GetMany(IEnumerable<string> keys);
IReadOnlyDictionary<string, T?> GetMany<T>(IEnumerable<string> keys);
void GetMany(IEnumerable<string> keys, Action<string, string?> onValue);
void GetMany<T>(IEnumerable<string> keys, Action<string, T?> onValue);
void SetMany(IEnumerable<KeyValuePair<string, string?>> values, int? targetLevel = null);
// 转换与事件
IConfigurationRoot ToMicrosoftConfiguration();
IConfigurationRoot ToMicrosoftConfiguration(DynamicReloadOptions? options);
IObservable<ConfigChangeEvent> ConfigChanges { get; }
}
string? Get(string key)
通过键路径获取配置值。
参数:
key: 配置键路径,使用冒号 : 分隔层级返回: 配置值字符串,如果不存在返回 null
示例:
var host = cfg.Get("Database:Host");
var port = cfg.Get("Database:Port");
var nested = cfg.Get("Services:Api:Url");
T? Get<T>(string key)
获取类型化的配置值。
参数:
key: 配置键返回: 转换后的值,如果不存在或转换失败返回 default(T)
示例:
var port = cfg.Get<int>("Database:Port");
var timeout = cfg.Get<int>("Database:Timeout");
var enabled = cfg.Get<bool>("Feature:Enabled");
bool Exists(string key)
检查配置键是否存在。
参数:
key: 配置键返回: 是否存在
示例:
if (cfg.Exists("OptionalFeature"))
{
// 处理可选功能
}
ICfgSection GetSection(string key)
获取指定键的配置节。
参数:
key: 配置节键路径返回: ICfgSection 配置节实例
示例:
var dbSection = cfg.GetSection("Database");
var host = dbSection.Get("Host");
var port = dbSection.Get<int>("Port");
IEnumerable<string> GetChildKeys()
获取所有顶级配置键。
返回: 顶级键名集合
示例:
foreach (var key in cfg.GetChildKeys())
{
Console.WriteLine($"顶级配置: {key}");
}
// 输出:
// 顶级配置: App
// 顶级配置: Database
// 顶级配置: Logging
IReadOnlyDictionary<string, string?> GetMany(IEnumerable<string> keys)
IReadOnlyDictionary<string, T?> GetMany<T>(IEnumerable<string> keys)
void GetMany(IEnumerable<string> keys, Action<string, string?> onValue)
void GetMany<T>(IEnumerable<string> keys, Action<string, T?> onValue)
批量获取多个配置值,减少锁竞争。
示例:
// 返回字典
var values = cfg.GetMany(new[] { "Database:Host", "Database:Port", "App:Name" });
// 返回类型化字典
var intValues = cfg.GetMany<int>(new[] { "Database:Port", "Database:Timeout" });
// 使用回调(零堆分配,性能更好)
cfg.GetMany(new[] { "Database:Host", "Database:Port" }, (key, value) =>
{
Console.WriteLine($"{key} = {value}");
});
// 类型化回调
cfg.GetMany<int>(new[] { "Database:Port", "Database:Timeout" }, (key, value) =>
{
Console.WriteLine($"{key} = {value}");
});
void Set(string key, string? value, int? targetLevel = null)
设置配置值。
参数:
key: 配置键value: 配置值targetLevel: 目标层级(可选,默认写入可写的最高层级)示例:
cfg.Set("App:Name", "NewName");
cfg.Set("Database:Port", "5433", targetLevel: 2);
void Remove(string key, int? targetLevel = null)
移除配置键。
参数:
key: 配置键targetLevel: 目标层级(可选,为 null 时从所有层级移除)示例:
cfg.Remove("DeprecatedSetting");
cfg.Remove("TempSetting", targetLevel: 1);
void SetMany(IEnumerable<KeyValuePair<string, string?>> values, int? targetLevel = null)
批量设置多个配置值,减少锁竞争。
示例:
cfg.SetMany(new Dictionary<string, string?>
{
["Database:Host"] = "new-host",
["Database:Port"] = "5433"
});
Task SaveAsync(int? targetLevel = null, CancellationToken cancellationToken = default)
保存配置到持久化存储。
参数:
targetLevel: 目标层级(可选,默认保存所有可写层级)cancellationToken: 取消令牌示例:
cfg.Set("App:Name", "NewName");
await cfg.SaveAsync();
// 只保存特定层级
await cfg.SaveAsync(targetLevel: 2);
IConfigurationRoot ToMicrosoftConfiguration()
IConfigurationRoot ToMicrosoftConfiguration(DynamicReloadOptions? options)
转换为 Microsoft.Extensions.Configuration 的 IConfigurationRoot。
参数:
options: 动态重载选项(可选),为 null 时返回静态快照返回: IConfigurationRoot 实例
示例:
// 静态快照
var msConfig = cfg.ToMicrosoftConfiguration();
// 支持动态重载
var dynamicConfig = cfg.ToMicrosoftConfiguration(new DynamicReloadOptions
{
ReloadOnChange = true,
DebounceInterval = TimeSpan.FromMilliseconds(500)
});
// 用于依赖注入
services.AddSingleton<IConfiguration>(msConfig);
IObservable<ConfigChangeEvent> ConfigChanges { get; }
配置变更的可观察序列(Rx Observable)。
示例:
cfg.ConfigChanges.Subscribe(e =>
{
Console.WriteLine($"配置变更时间: {e.Timestamp}");
foreach (var (key, change) in e.Changes)
{
Console.WriteLine($" [{change.Type}] {key}: {change.OldValue} -> {change.NewValue}");
}
});
ICfgRoot 还提供了一些便捷的扩展方法:
bool TryGet<T>(this ICfgRoot root, string key, out T? value)
尝试获取配置值。
示例:
if (cfg.TryGet<int>("Database:Port", out var port))
{
Console.WriteLine($"端口: {port}");
}
T GetRequired<T>(this ICfgRoot root, string key)
获取必需的配置值,如果不存在则抛出异常。
示例:
var connectionString = cfg.GetRequired<string>("Database:ConnectionString");
T? GetOrDefault<T>(this ICfgRoot root, string key, T? defaultValue = default)
获取配置值,如果不存在则返回默认值。
示例:
var timeout = cfg.GetOrDefault("Database:Timeout", 30);
var retryCount = cfg.GetOrDefault<int>("Database:RetryCount", 3);
string GetMasked(this ICfgRoot cfg, string key)
获取脱敏后的配置值(用于日志输出)。
示例:
// 日志输出时使用脱敏值
logger.LogInformation("连接字符串: {ConnectionString}", cfg.GetMasked("Database:ConnectionString"));
// 输出: 连接字符串: Ser***ion
IReadOnlyDictionary<string, string> GetMaskedSnapshot(this ICfgRoot cfg)
获取所有配置的脱敏快照(用于调试)。
示例:
var snapshot = cfg.GetMaskedSnapshot();
foreach (var (key, value) in snapshot)
{
Console.WriteLine($"{key}: {value}");
}
var cfg = new CfgBuilder()
.AddJson("config.json", level: 0, writeable: false)
.AddJson("config.local.json", level: 1, writeable: true, isPrimaryWriter: true, optional: true, reloadOnChange: true)
.Build();
// 读取配置
var host = cfg.Get("Database:Host");
var port = cfg.Get<int>("Database:Port");
// 检查配置是否存在
if (cfg.Exists("OptionalFeature:Enabled"))
{
var enabled = cfg.Get<bool>("OptionalFeature:Enabled");
}
// 获取所有顶级键
foreach (var key in cfg.GetChildKeys())
{
Console.WriteLine($"配置节: {key}");
}
// 获取配置节
var dbSection = cfg.GetSection("Database");
var connString = $"Host={dbSection.Get("Host")};Port={dbSection.Get("Port")}";
// 批量读取
var values = cfg.GetMany(new[] { "App:Name", "App:Version" });
// 使用扩展方法
var timeout = cfg.GetOrDefault("Database:Timeout", 30);
var connStr = cfg.GetRequired<string>("Database:ConnectionString");
// 修改配置
cfg.Set("App:Name", "NewName");
cfg.SetMany(new Dictionary<string, string?>
{
["Database:Host"] = "new-host",
["Database:Port"] = "5433"
});
// 保存配置
await cfg.SaveAsync();
// 订阅配置变更
cfg.ConfigChanges.Subscribe(e =>
{
Console.WriteLine("配置已更新");
});
// 转换为 Microsoft Configuration
var msConfig = cfg.ToMicrosoftConfiguration();
// 获取脱敏快照用于调试
var maskedSnapshot = cfg.GetMaskedSnapshot();