IMPROVEMENTS.md 7.3 KB

Apq.Cfg 改进方向分析

本文档针对架构设计、动态重载、性能优化、编码检测四个方面,分析可能的改进方向。


1. 架构设计 ⭐⭐⭐⭐ → ⭐⭐⭐⭐⭐

改进点 说明
依赖注入支持 添加 IServiceCollection 扩展方法,如 services.AddApqCfg(builder => ...)
配置源优先级动态调整 支持运行时调整 level,而非仅构建时固定
配置分组/命名空间 支持 cfg.GetSection("Database") 返回子配置对象
配置验证 添加 IConfigValidator 接口,支持启动时验证配置完整性
插件化加载 支持通过反射或 MEF 动态加载扩展包,无需显式引用
ConvertValue 代码重复 MergedCfgRootCfgRootExtensions 中有重复的类型转换逻辑,应抽取为共享工具类
// 示例:依赖注入支持
services.AddApqCfg(cfg => cfg
    .AddJson("config.json", level: 0)
    .AddEnvironmentVariables(level: 1)
    .WithValidation<AppSettings>());

2. 动态重载实现 ⭐⭐⭐⭐ → ⭐⭐⭐⭐⭐ ✅ 已完成

改进点 说明 状态
可配置的重载策略 支持 Eager(立即)/ Lazy(访问时)/ Manual(手动)三种模式 ✅ 已实现
变更过滤器 支持只监听特定 key 前缀的变更,减少不必要的通知 ✅ 已实现
变更批次 ID 为每次变更事件添加唯一 ID,便于追踪和日志 ✅ 已实现
重载失败回滚 配置源加载失败时保留旧值,而非清空 ✅ 已实现
异步事件处理 OnMergedChangesAsync 支持异步订阅者 ✅ 已实现
变更历史 可选的变更历史记录,支持查询最近 N 次变更 ✅ 已实现

使用示例

// 配置动态重载选项
var msConfig = cfg.ToMicrosoftConfiguration(new DynamicReloadOptions
{
    DebounceMs = 100,                           // 防抖时间
    Strategy = ReloadStrategy.Eager,            // 重载策略:Eager/Lazy/Manual
    KeyPrefixFilters = new[] { "Database:" },   // 只监听 Database: 前缀的变更
    RollbackOnError = true,                     // 重载失败时回滚
    HistorySize = 10                            // 保留最近 10 次变更历史
});

// 订阅变更事件(带批次 ID)
cfg.ConfigChanges.Subscribe(e =>
{
    Console.WriteLine($"[{e.BatchId}] {e.Timestamp}: {e.Changes.Count} 个配置变更");
});

// 订阅重载错误事件
cfg.ReloadErrors.Subscribe(e =>
{
    Console.WriteLine($"重载失败: {e.Exception.Message}, 已回滚: {e.RolledBack}");
});

// 手动重载(Manual 策略)
cfg.Reload();

// 获取变更历史
var history = cfg.GetChangeHistory();

3. 性能优化 ⭐⭐⭐⭐ → ⭐⭐⭐⭐⭐ ✅ 部分完成

改进点 说明 状态
值缓存 Get<T> 的类型转换结果进行缓存,避免重复解析 ✅ 已实现
Span/Memory 优化 键路径解析使用 ReadOnlySpan<char> 避免字符串分配 ✅ 已实现
对象池 使用 ArrayPool<T> 替代 ThreadStatic,更好的内存复用 待实现
批量操作 API 添加 GetMany(keys) / SetMany(dict) 减少锁竞争 ✅ 已实现
冷热数据分离 高频访问的 key 使用更快的数据结构(如 FrozenDictionary .NET 8+) ✅ 已实现
Source Generator 使用源生成器在编译时生成强类型配置类,零反射 ✅ 已实现
// 示例:批量操作
var values = cfg.GetMany(new[] { "App:Name", "App:Version", "App:Debug" });

// 示例:Source Generator 生成的强类型配置
[CfgSection("Database")]
public partial class DatabaseConfig
{
    public string ConnectionString { get; set; }
    public int Timeout { get; set; }
    public PoolSettings Pool { get; set; }  // 嵌套对象
    public List<string> AllowedHosts { get; set; }  // 集合
}

[CfgSection]  // 自动推断为 "Pool"
public partial class PoolSettings
{
    public int MinSize { get; set; }
    public int MaxSize { get; set; }
}

// 使用方式(零反射)
var dbConfig = DatabaseConfig.BindFrom(cfg.GetSection("Database"));
// 或使用生成的扩展方法
var dbConfig = cfg.GetDatabaseConfig();

4. 编码检测 ⭐⭐⭐⭐ → ⭐⭐⭐⭐⭐

改进点 说明
编码检测缓存 缓存已检测文件的编码结果,避免每次读取都检测
BOM 优先检测 先检查 BOM 标记(更快更准确),再用 UTF.Unknown
编码转换策略 支持配置:保持原编码 / 统一转 UTF-8 / 按文件类型决定
编码检测日志 可选的日志输出,记录检测结果和置信度
自定义编码映射 支持用户指定特定文件的编码,覆盖自动检测
写入编码可配置 当前固定 UTF-8 无 BOM,应支持配置(如 .ps1 需要 UTF-8 BOM)
// 示例:编码策略配置
.AddJson("config.json", encoding: new EncodingOptions
{
    ReadStrategy = EncodingStrategy.AutoDetect,
    WriteEncoding = Encoding.UTF8,
    FallbackEncoding = Encoding.GetEncoding("GB2312")
})

优先级建议

优先级 改进项 理由
P0 依赖注入支持 .NET 生态标配,提升易用性
P0 ConvertValue 代码去重 技术债务,维护成本
P1 批量操作 API 性能提升明显
P1 重载失败回滚 稳定性保障
P1 写入编码可配置 实际需求(如 PowerShell)
P2 值缓存 高频场景性能提升
P2 变更过滤器 减少不必要的处理
P3 Source Generator 高级特性,开发成本高

实现路线图

阶段一:基础完善

  • 抽取 ConvertValue 为共享工具类
  • 添加依赖注入扩展 Apq.Cfg.DependencyInjection
  • 写入编码可配置

阶段二:稳定性增强

  • 重载失败回滚机制 ✅ 2025-12-25
  • 变更批次 ID 和日志 ✅ 2025-12-25
  • 编码检测缓存

阶段三:性能提升

  • 批量操作 API ✅ 2025-12-25
  • 值缓存机制 ✅ 2025-12-25
  • FrozenDictionary 支持(.NET 8+) ✅ 2025-12-25
  • Span/Memory 键路径解析优化 ✅ 2025-12-25

阶段四:高级特性

  • Source Generator 强类型配置 ✅ 2025-12-26
  • 配置验证框架
  • 变更历史记录 ✅ 2025-12-25

已完成的动态重载改进(2025-12-25)

  • 可配置的重载策略(Eager/Lazy/Manual)
  • 变更过滤器(KeyPrefixFilters)
  • 变更批次 ID(BatchId)
  • 重载失败回滚(RollbackOnError)
  • 异步事件处理(OnMergedChangesAsync)
  • 变更历史记录(HistorySize)

已完成的性能优化改进(2025-12-25)

  • 值缓存机制(ValueCache)
  • Span/Memory 键路径解析(KeyPathParser)
  • 批量操作 API(GetMany/SetMany)
  • FrozenDictionary 支持(FastCollections,.NET 8+)

已完成的 Source Generator(2025-12-26)

  • CfgSectionAttribute 特性标记
  • 编译时代码生成(零反射)
  • 支持简单类型、嵌套对象、数组、List、Dictionary、HashSet
  • 自动生成 ICfgRoot 扩展方法
  • 完全兼容 Native AOT

分析日期:2025-12-25 更新日期:2025-12-26