改进 ConfigProvider 的线程安全性,使用 ConcurrentDictionary 并添加锁机制。 优化键集合处理,提升性能;修复列表映射问题,支持基础类型转换。 增强模型绑定功能,支持自动更新和线程安全回调。 新增单元测试覆盖关键场景,重构测试代码以提升可读性。 新增详细使用说明文档,帮助开发者快速上手配置系统。 移除冗余引用,保持代码整洁。
智能大石头 authored at 2025-09-22 16:18:06
3.82 KiB
X
# IConfigProvider ÅäÖÃÌåϵʹÓÃ˵Ã÷ ±¾Îĵµ½éÉÜ NewLife.Configuration ÅäÖÃÌåϵµÄ¼Ü¹¹¡¢Ó÷¨ÓëÀ©Õ¹µã£¬ÊÊÓÃÓÚ NewLife.Core ²Ö¿â¡£ ## 1. ¼Ü¹¹¸ÅÀÀ - ºËÐijéÏó - `IConfigProvider`£ºÅäÖÃÌṩÕßͳһ½Ó¿Ú£¬±©Â¶¼üÖµ·ÃÎÊ¡¢Ê÷ÐζηÃÎÊ¡¢Ä£ÐÍ Load/Save/Bind¡¢±ä¸ü֪ͨ¡£ - `IConfigSection`£ºÅäÖöΣ¨½Úµã£©£¬¼ü/Öµ/×¢ÊÍÓë×Ó¼¶£¨Ê÷ÐΣ©½á¹¹¡£ - `GetConfigCallback`£º»ñÈ¡ÅäÖõÄίÍУ¬¿ÉÓÃÓÚ×¢Èëµ½ÆäËüÄ£¿éÖнøÐа´¼ü»ñÈ¡¡£ - ³éÏó»ùÀà - `ConfigProvider`£ºÊµÏÖ `IConfigProvider` µÄ»ùÀ࣬ÌṩÀÁ¼ÓÔØ¡¢¼ü·¾¶·ÃÎÊ¡¢Ä£ÐÍÓ³Éä¡¢°ó¶¨Óë±ä¸ü֪ͨ¡¢Ä¬ÈÏÌṩÕß×¢²áÓ빤³§·½·¨¡£ - `FileConfigProvider`£ºÎļþÐÍÌṩÕß»ùÀ࣬·â×°Îļþ¶Áд¡¢ÂÖѯÈȼÓÔØ£¨`TimerX`£©¡£ - ¾ßÌåʵÏÖ - `XmlConfigProvider`£ºXML Îļþ¡£ - `InIConfigProvider`£ºINI Îļþ¡£ - `JsonConfigProvider`£ºJSON Îļþ£¨Ö§³Ö×¢Ê͵ÄÔ¤´¦Àí£©¡£ - `HttpConfigProvider`£ºÅäÖÃÖÐÐÄ£¨Ðdz¾µÈ£©£¬´ø±¾µØ»º´æ¡¢°æ±¾ÓëÔöÁ¿Éϱ¨£¬Ö§³Ö¶¨Ê±Ë¢Ð¡£ - `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¡£ --- ÒÔÉÏ¡£