|
|
3 часов назад | |
|---|---|---|
| .workflow | 8 часов назад | |
| Apq.Cfg | 3 часов назад | |
| Apq.Cfg.Apollo | 3 часов назад | |
| Apq.Cfg.Consul | 3 часов назад | |
| Apq.Cfg.Database | 3 часов назад | |
| Apq.Cfg.Etcd | 3 часов назад | |
| Apq.Cfg.Ini | 3 часов назад | |
| Apq.Cfg.Nacos | 3 часов назад | |
| Apq.Cfg.Redis | 3 часов назад | |
| Apq.Cfg.SourceGenerator | 5 часов назад | |
| Apq.Cfg.Toml | 3 часов назад | |
| Apq.Cfg.Xml | 3 часов назад | |
| Apq.Cfg.Yaml | 3 часов назад | |
| Samples | 1 день назад | |
| benchmarks | 5 часов назад | |
| buildTools | 5 часов назад | |
| docs | 9 часов назад | |
| tests | 5 часов назад | |
| versions | 8 часов назад | |
| .gitignore | 9 часов назад | |
| Apq.Cfg.sln | 9 часов назад | |
| CLAUDE.md | 9 часов назад | |
| Directory.Build.props | 3 часов назад | |
| LICENSE | 6 дней назад | |
| README.md | 9 часов назад |
统一配置管理系统,支持多种配置格式和多层级配置合并。
仓库地址:https://gitee.com/apq/Apq.Cfg
GetSection),简化嵌套配置访问GetMany、SetMany 减少锁竞争,提升并发性能
AddApqCfg 和 ConfigureApqCfg<T> 扩展方法ConfigChanges 订阅配置变更事件.NET 6.0 / 7.0 / 8.0 / 9.0
| 包名 | 说明 |
|---|---|
| Apq.Cfg | 核心库,包含 JSON 支持 |
| Apq.Cfg.Ini | INI 格式支持 |
| Apq.Cfg.Xml | XML 格式支持 |
| Apq.Cfg.Yaml | YAML 格式支持 |
| Apq.Cfg.Toml | TOML 格式支持 |
| Apq.Cfg.Redis | Redis 配置源 |
| Apq.Cfg.Database | 数据库配置源 |
| Apq.Cfg.Consul | Consul 配置中心 |
| Apq.Cfg.Etcd | Etcd 配置中心 |
| Apq.Cfg.Nacos | Nacos 配置中心 |
| Apq.Cfg.Apollo | Apollo 配置中心 |
| Apq.Cfg.SourceGenerator | 源生成器,支持 Native AOT |
using Apq.Cfg;
var cfg = CfgBuilder.Create()
.AddJson("config.json", level: 0, writeable: false)
.AddJson("config.local.json", level: 1, writeable: true, isPrimaryWriter: true)
.AddEnvironmentVariables(level: 2, prefix: "APP_")
.Build();
// 读取配置
var value = cfg.Get("Database:ConnectionString");
// 使用配置节简化嵌套访问
var dbSection = cfg.GetSection("Database");
var host = dbSection.Get("Host");
var port = dbSection.Get<int>("Port");
// 枚举配置节的子键
foreach (var key in dbSection.GetChildKeys())
{
Console.WriteLine($"{key}: {dbSection.Get(key)}");
}
// 修改配置
cfg.Set("App:LastRun", DateTime.Now.ToString());
await cfg.SaveAsync();
支持两种批量获取方式:
// 方式1:返回字典(简单易用)
var values = cfg.GetMany(new[] { "Key1", "Key2", "Key3" });
foreach (var kv in values)
{
Console.WriteLine($"{kv.Key}: {kv.Value}");
}
// 方式2:回调方式(高性能,零堆分配)
cfg.GetMany(new[] { "Key1", "Key2", "Key3" }, (key, value) =>
{
Console.WriteLine($"{key}: {value}");
});
// 带类型转换的批量获取
cfg.GetMany<int>(new[] { "Port1", "Port2" }, (key, value) =>
{
Console.WriteLine($"{key}: {value}");
});
// 批量设置
cfg.SetMany(new Dictionary<string, string?>
{
["Key1"] = "Value1",
["Key2"] = "Value2"
});
await cfg.SaveAsync();
支持配置文件变更时自动更新,无需重启应用:
using Apq.Cfg;
using Apq.Cfg.Changes;
using Microsoft.Extensions.Primitives;
// 构建配置(启用 reloadOnChange)
var cfg = CfgBuilder.Create()
.AddJson("config.json", level: 0, writeable: false, reloadOnChange: true)
.AddJson("config.local.json", level: 1, writeable: true, reloadOnChange: true)
.AddEnvironmentVariables(level: 2, prefix: "APP_")
.Build();
// 获取支持动态重载的 Microsoft Configuration
var msConfig = cfg.ToMicrosoftConfiguration(new DynamicReloadOptions
{
DebounceMs = 100, // 防抖时间窗口(毫秒)
EnableDynamicReload = true // 启用动态重载
});
// 方式1:使用 IChangeToken 监听变更
ChangeToken.OnChange(
() => msConfig.GetReloadToken(),
() => Console.WriteLine("配置已更新"));
// 方式2:使用 Rx 订阅配置变更事件
cfg.ConfigChanges.Subscribe(e =>
{
foreach (var (key, change) in e.Changes)
{
Console.WriteLine($"[{change.Type}] {key}: {change.OldValue} -> {change.NewValue}");
}
});
所有文件配置源(JSON、INI、XML、YAML、TOML)均支持智能编码处理:
编码映射:支持完整路径、通配符、正则表达式三种匹配方式
var cfg = CfgBuilder.Create()
// 为特定文件指定读取编码
.AddReadEncodingMapping(@"C:\legacy\old.ini", Encoding.GetEncoding("GB2312"))
// 为 PowerShell 脚本指定写入编码(UTF-8 BOM)
.AddWriteEncodingMappingWildcard("*.ps1", new UTF8Encoding(true))
// 设置编码检测置信度阈值(默认 0.6)
.WithEncodingConfidenceThreshold(0.7f)
// 启用编码检测日志
.WithEncodingDetectionLogging(result => Console.WriteLine($"检测到编码: {result}"))
.AddJson("config.json", level: 0, writeable: true)
.Build();
支持与 Microsoft.Extensions.DependencyInjection 无缝集成:
using Apq.Cfg;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
var services = new ServiceCollection();
// 注册 Apq.Cfg 配置
services.AddApqCfg(cfg => cfg
.AddJson("config.json", level: 0, writeable: false)
.AddJson("config.local.json", level: 1, writeable: true, isPrimaryWriter: true));
// 绑定强类型配置
services.ConfigureApqCfg<DatabaseOptions>("Database");
services.ConfigureApqCfg<LoggingOptions>("Logging");
var provider = services.BuildServiceProvider();
// 通过 DI 获取配置
var cfgRoot = provider.GetRequiredService<ICfgRoot>();
var dbOptions = provider.GetRequiredService<IOptions<DatabaseOptions>>().Value;
public class DatabaseOptions
{
public string? Host { get; set; }
public int Port { get; set; }
public string? Name { get; set; }
}
支持 Consul、Etcd、Nacos、Apollo 等远程配置中心,支持热重载:
using Apq.Cfg;
using Apq.Cfg.Consul;
using Apq.Cfg.Etcd;
using Apq.Cfg.Nacos;
using Apq.Cfg.Apollo;
// 使用 Consul 配置中心
var cfg = CfgBuilder.Create()
.AddJson("config.json", level: 0)
.AddConsul(options => {
options.Address = "http://localhost:8500";
options.KeyPrefix = "app/config/";
options.EnableHotReload = true; // 启用热重载
}, level: 10)
.Build();
// 使用 Etcd 配置中心
var cfg2 = CfgBuilder.Create()
.AddJson("config.json", level: 0)
.AddEtcd(options => {
options.Endpoints = new[] { "http://localhost:2379" };
options.KeyPrefix = "/app/config/";
options.EnableHotReload = true; // 启用热重载
}, level: 10)
.Build();
// 使用 Nacos 配置中心
var cfg3 = CfgBuilder.Create()
.AddJson("config.json", level: 0)
.AddNacos(options => {
options.ServerAddresses = "localhost:8848";
options.Namespace = "public";
options.DataId = "app-config";
options.Group = "DEFAULT_GROUP";
options.Username = "nacos"; // 可选
options.Password = "nacos"; // 可选
options.DataFormat = NacosDataFormat.Json; // 支持 Json/Yaml/Properties
}, level: 10)
.Build();
// 使用 Apollo 配置中心
var cfg4 = CfgBuilder.Create()
.AddJson("config.json", level: 0)
.AddApollo(options => {
options.AppId = "my-app";
options.MetaServer = "http://localhost:8080";
options.Cluster = "default";
options.Namespaces = new[] { "application", "common" };
options.Secret = "your-secret"; // 可选,用于访问控制
options.EnableHotReload = true; // 启用热重载
}, level: 10)
.Build();
// 订阅配置变更
cfg.ConfigChanges.Subscribe(change => {
Console.WriteLine($"配置变更: {change.Key} = {change.NewValue}");
});
| 配置中心 | 写入支持 | 数据格式 | 热重载 | 特点 |
|---|---|---|---|---|
| Consul | ✅ | KV/JSON/YAML | ✅ Blocking Query | KV 存储,支持前缀监听 |
| Etcd | ✅ | KV/JSON | ✅ Watch API | 强一致性,支持前缀监听 |
| Nacos | ✅ | JSON/YAML/Properties | ❌ | 支持命名空间、分组、多 DataId |
| Apollo | ❌ | Properties | ✅ 长轮询 + 通知 | 支持多环境、集群、命名空间 |
使用 Apq.Cfg.SourceGenerator 包可以在编译时生成零反射的配置绑定代码,完全支持 Native AOT:
dotnet add package Apq.Cfg.SourceGenerator
定义配置类时使用 [CfgSection] 特性标记,类必须是 partial 的:
using Apq.Cfg;
[CfgSection("AppSettings")]
public partial class AppConfig
{
public string? Name { get; set; }
public int Port { get; set; }
public DatabaseConfig? Database { get; set; }
}
[CfgSection]
public partial class DatabaseConfig
{
public string? ConnectionString { get; set; }
public int Timeout { get; set; } = 30;
}
源生成器会自动生成 BindFrom 和 BindTo 静态方法:
// 构建配置
var cfgRoot = CfgBuilder.Create()
.AddJson("config.json")
.AddIni("config.ini")
.Build();
// 使用源生成器绑定配置(零反射)
var appConfig = AppConfig.BindFrom(cfgRoot.GetSection("AppSettings"));
Console.WriteLine($"App: {appConfig.Name}");
Console.WriteLine($"Port: {appConfig.Port}");
Console.WriteLine($"Database: {appConfig.Database?.ConnectionString}");
源生成器支持的类型:
string、int、long、bool、double、decimal、DateTime、Guid、枚举等T[]、List<T>、HashSet<T>、Dictionary<TKey, TValue>[CfgSection])# 构建
dotnet build
# 运行单元测试
dotnet test
# 运行性能测试(需要管理员权限以获得准确结果)
cd benchmarks/Apq.Cfg.Benchmarks
dotnet run -c Release
最后运行时间: 2025-12-26
| 框架 | 通过 | 失败 | 跳过 | 总计 | 状态 |
|---|---|---|---|---|---|
| .NET 6.0 | 290 | 0 | 0 | 290 | ✅ 通过 |
| .NET 8.0 | 290 | 0 | 0 | 290 | ✅ 通过 |
| .NET 9.0 | 290 | 0 | 0 | 290 | ✅ 通过 |
详细测试覆盖情况见 tests/README.md
详细性能测试结果见 benchmarks/BENCHMARK_RESULTS.md
MIT License