解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
4.67 KiB
X
# IConfigProvider 配置体系使用说明 本文档介绍 NewLife.Configuration 配置体系的架构、用法与扩展点,适用于 NewLife.Core 仓库。 ## 1. 架构概览 - 核心抽象 - `IConfigProvider`:配置提供者统一接口,暴露键值访问、树形段访问、模型 Load/Save/Bind、变更通知。 - `IConfigSection`:配置段(节点),键/值/注释与子级(树形)结构。 - `GetConfigCallback`:获取配置的委托,可用于注入到其它模块中进行按键获取。 - 抽象基类 - `ConfigProvider`:实现 `IConfigProvider` 的基类,提供懒加载、键路径访问、模型映射、绑定与变更通知、默认提供者注册与工厂方法。 - `FileConfigProvider`:文件型提供者基类,封装文件读写、轮询热加载(`TimerX`)。 - 具体实现 - `XmlConfigProvider`:XML 文件。 - `InIConfigProvider`:INI 文件。 - `JsonConfigProvider`:JSON 文件(支持注释的预处理)。 - `HttpConfigProvider`:配置中心(星尘等),带本地缓存、版本与增量上报,支持定时刷新。 - `ApolloConfigProvider`:针对 Apollo 的适配(命名空间聚合读取)。 - `CompositeConfigProvider`:复合提供者,聚合多个提供者,读取优先、保存逐个尝试。 - 辅助与模型 - `Config<T>`:配置模型基类,`Current` 通过标注 `ConfigAttribute` 自动选择提供者并加载/绑定。 - `ConfigHelper`:在模型与配置树之间进行映射(`MapTo/MapFrom`),支持数组、`IList<T>`、复杂对象、字典。 - `IConfigMapping`:自定义映射接口,用户可在模型中实现以获得完全控制的映射逻辑。 ## 2. 典型用法 - 定义模型 ```csharp [Config("core", provider: null)] // 使用默认提供者(可全局切换) public class CoreConfig : Config<CoreConfig> { [Description("全局调试。XTrace.Debug")] public bool Debug { get; set; } public string? LogPath { get; set; } public SysConfig Sys { get; set; } = new(); } public class SysConfig { [Description("用于标识系统的英文名,不能有空格")] public string Name { get; set; } = ""; public string? DisplayName { get; set; } } ``` - 加载/保存 ```csharp var cfg = CoreConfig.Current; // 首次会绑定并自动落盘(若新建) cfg.Debug = true; cfg.Save(); ``` - 直接使用提供者 ```csharp var prv = ConfigProvider.Create("config")!; // xml 默认 .config prv.Init("core"); prv.LoadAll(); var debug = prv["Debug"]; // 键路径支持冒号分隔:"Sys:Name" var section = prv.GetSection("Sys:Name"); ``` - 绑定热更新 ```csharp var cfg = new CoreConfig(); var prv = new JsonConfigProvider { FileName = "Config/core.json" }; prv.Bind(cfg, autoReload: true); // 文件变更/远端推送将刷新 cfg ``` - 复合提供者 ```csharp var local = new JsonConfigProvider { FileName = "Config/appsettings.json" }; var remote = new HttpConfigProvider { Server = "http://conf", AppId = "Demo" }; var composite = new CompositeConfigProvider(local, remote); var name = composite["Sys:Name"]; // 读取时按顺序查找 ``` ## 3. 扩展点 - 新建文件提供者:继承 `FileConfigProvider`,重写 `OnRead` 与 `GetString/OnWrite` 即可。 - 新建远端提供者:继承 `ConfigProvider`,实现 `LoadAll/SaveAll` 与定时刷新(可选)。 - 注册为默认:`ConfigProvider.Register<MyProvider>("my");`,随后通过 `ConfigProvider.Create("my")` 使用。 ## 4. 行为与约定 - 键路径语法:`A:B:C` 表示树形下钻。 - `Keys` 默认只返回根下第一层键;具体实现可覆盖返回深层键集合。 - `IsNew` 用于指示配置源是否首次创建,`Config<T>.Current` 会据此决定是否持久化默认值。 - 注释:模型属性上的 `DescriptionAttribute/DisplayNameAttribute` 会写入配置项注释。 - 列表与数组:`ConfigHelper` 支持 `T[]` 与 `IList<T>`;基元类型元素会进行类型转换。 ## 5. 本仓库优化点(已处理) - 修复:`ConfigHelper.MapToList` 对基元类型元素进行 `ChangeType` 转换,避免 `List<int>` 被写成字符串列表。 - 健壮性:`ConfigProvider.Keys` 访问前调用 `EnsureLoad()`,避免未加载即访问导致的空集合误判。 - 并发安全:`ConfigProvider` 的绑定集合改为 `ConcurrentDictionary`,防止变更通知期间枚举异常。 ## 6. 注意事项 - 性能:反射与树形映射不应放在热点高频路径;如需频繁访问,请缓存配置或使用强类型绑定。 - 线程安全:模型绑定与刷新回调不要执行耗时操作,避免阻塞通知链路。 - 兼容性:针对 .NET Framework 与 .NET Standard 均已适配,无需使用平台专属 API。 --- 以上。