Browse Source

完善示例项目

黄中银 2 weeks ago
parent
commit
eec2114c9d

+ 10 - 10
Apq.Cfg/README.md

@@ -46,8 +46,8 @@ using Apq.Cfg;
 
 // 构建配置
 var cfg = new CfgBuilder()
-    .AddJson("appsettings.json", level: 0, writeable: false)
-    .AddJson("appsettings.local.json", level: 1, writeable: true, isPrimaryWriter: true)
+    .AddJson("config.json", level: 0, writeable: false)
+    .AddJson("config.local.json", level: 1, writeable: true, isPrimaryWriter: true)
     .AddEnvironmentVariables(level: 2, prefix: "APP_")
     .Build();
 
@@ -71,8 +71,8 @@ await cfg.SaveAsync();
 
 ```csharp
 var cfg = new CfgBuilder()
-    .AddJson("appsettings.json", level: 0)           // 基础配置(最低优先级)
-    .AddJson("appsettings.local.json", level: 1)     // 本地覆盖
+    .AddJson("config.json", level: 0)           // 基础配置(最低优先级)
+    .AddJson("config.local.json", level: 1)     // 本地覆盖
     .AddEnvironmentVariables(level: 2)               // 环境变量(最高优先级)
     .Build();
 ```
@@ -208,7 +208,7 @@ var cfg = new CfgBuilder()
 // 方式1:通过 CfgBuilder 设置(推荐)
 var cfg = new CfgBuilder()
     .WithEncodingConfidenceThreshold(0.7f)
-    .AddJson("appsettings.json", level: 0, writeable: false)
+    .AddJson("config.json", level: 0, writeable: false)
     .Build();
 
 // 方式2:直接设置静态属性
@@ -227,7 +227,7 @@ FileCfgSourceBase.EncodingConfidenceThreshold = 0.7f;
 
 ```csharp
 var cfg = new CfgBuilder()
-    .AddJson("appsettings.json", level: 0, reloadOnChange: true)
+    .AddJson("config.json", level: 0, reloadOnChange: true)
     .Build();
 
 // 配置文件变更后会自动重新加载
@@ -242,8 +242,8 @@ using Apq.Cfg.Changes;
 using Microsoft.Extensions.Primitives;
 
 var cfg = new CfgBuilder()
-    .AddJson("appsettings.json", level: 0, reloadOnChange: true)
-    .AddJson("appsettings.local.json", level: 1, reloadOnChange: true)
+    .AddJson("config.json", level: 0, reloadOnChange: true)
+    .AddJson("config.local.json", level: 1, reloadOnChange: true)
     .Build();
 
 // 获取支持动态重载的 Microsoft Configuration
@@ -284,8 +284,8 @@ var services = new ServiceCollection();
 
 // 注册 Apq.Cfg 配置
 services.AddApqCfg(cfg => cfg
-    .AddJson("appsettings.json", level: 0, writeable: false)
-    .AddJson("appsettings.local.json", level: 1, writeable: true, isPrimaryWriter: true));
+    .AddJson("config.json", level: 0, writeable: false)
+    .AddJson("config.local.json", level: 1, writeable: true, isPrimaryWriter: true));
 
 // 绑定强类型配置
 services.ConfigureApqCfg<DatabaseOptions>("Database");

+ 6 - 6
README.md

@@ -34,8 +34,8 @@
 using Apq.Cfg;
 
 var cfg = new CfgBuilder()
-    .AddJson("appsettings.json", level: 0, writeable: false)
-    .AddJson("appsettings.local.json", level: 1, writeable: true, isPrimaryWriter: true)
+    .AddJson("config.json", level: 0, writeable: false)
+    .AddJson("config.local.json", level: 1, writeable: true, isPrimaryWriter: true)
     .AddEnvironmentVariables(level: 2, prefix: "APP_")
     .Build();
 
@@ -69,8 +69,8 @@ using Microsoft.Extensions.Primitives;
 
 // 构建配置(启用 reloadOnChange)
 var cfg = new CfgBuilder()
-    .AddJson("appsettings.json", level: 0, writeable: false, reloadOnChange: true)
-    .AddJson("appsettings.local.json", level: 1, writeable: true, reloadOnChange: true)
+    .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();
 
@@ -141,8 +141,8 @@ var services = new ServiceCollection();
 
 // 注册 Apq.Cfg 配置
 services.AddApqCfg(cfg => cfg
-    .AddJson("appsettings.json", level: 0, writeable: false)
-    .AddJson("appsettings.local.json", level: 1, writeable: true, isPrimaryWriter: true));
+    .AddJson("config.json", level: 0, writeable: false)
+    .AddJson("config.local.json", level: 1, writeable: true, isPrimaryWriter: true));
 
 // 绑定强类型配置
 services.ConfigureApqCfg<DatabaseOptions>("Database");

+ 6 - 0
Samples/Apq.Cfg.Samples/Apq.Cfg.Samples.csproj

@@ -2,10 +2,16 @@
 
   <ItemGroup>
     <ProjectReference Include="..\..\Apq.Cfg\Apq.Cfg.csproj" />
+    <ProjectReference Include="..\..\Apq.Cfg.Ini\Apq.Cfg.Ini.csproj" />
+    <ProjectReference Include="..\..\Apq.Cfg.Xml\Apq.Cfg.Xml.csproj" />
     <ProjectReference Include="..\..\Apq.Cfg.Yaml\Apq.Cfg.Yaml.csproj" />
     <ProjectReference Include="..\..\Apq.Cfg.Toml\Apq.Cfg.Toml.csproj" />
   </ItemGroup>
 
+  <ItemGroup>
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
+  </ItemGroup>
+
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <TargetFramework>net8.0</TargetFramework>

+ 635 - 63
Samples/Apq.Cfg.Samples/Program.cs

@@ -1,76 +1,648 @@
+using System.Text;
 using Apq.Cfg;
+using Apq.Cfg.Changes;
+using Apq.Cfg.Ini;
+using Apq.Cfg.Xml;
 using Apq.Cfg.Yaml;
 using Apq.Cfg.Toml;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Primitives;
 
-Console.WriteLine("=== Apq.Cfg 示例 ===\n");
+Console.WriteLine("╔══════════════════════════════════════════════════════════════╗");
+Console.WriteLine("║              Apq.Cfg 完整功能示例                            ║");
+Console.WriteLine("╚══════════════════════════════════════════════════════════════╝\n");
 
-// 创建示例配置文件
-var appSettingsPath = Path.Combine(AppContext.BaseDirectory, "appsettings.json");
-var localSettingsPath = Path.Combine(AppContext.BaseDirectory, "appsettings.local.json");
+var baseDir = AppContext.BaseDirectory;
 
-// 写入基础配置
-File.WriteAllText(appSettingsPath, """
+// ============================================================================
+// 示例 1: 基础用法 - JSON 配置与层级覆盖
+// ============================================================================
+await Demo1_BasicUsage(baseDir);
+
+// ============================================================================
+// 示例 2: 多格式支持 - INI、XML、YAML、TOML
+// ============================================================================
+await Demo2_MultiFormat(baseDir);
+
+// ============================================================================
+// 示例 3: 配置节 (GetSection) 与子键枚举
+// ============================================================================
+await Demo3_ConfigSection(baseDir);
+
+// ============================================================================
+// 示例 4: 批量操作 - GetMany / SetMany
+// ============================================================================
+await Demo4_BatchOperations(baseDir);
+
+// ============================================================================
+// 示例 5: 类型转换
+// ============================================================================
+await Demo5_TypeConversion(baseDir);
+
+// ============================================================================
+// 示例 6: 动态配置重载
+// ============================================================================
+await Demo6_DynamicReload(baseDir);
+
+// ============================================================================
+// 示例 7: 依赖注入集成
+// ============================================================================
+await Demo7_DependencyInjection(baseDir);
+
+// ============================================================================
+// 示例 8: 编码映射配置
+// ============================================================================
+await Demo8_EncodingMapping(baseDir);
+
+Console.WriteLine("\n╔══════════════════════════════════════════════════════════════╗");
+Console.WriteLine("║              所有示例执行完成                                ║");
+Console.WriteLine("╚══════════════════════════════════════════════════════════════╝");
+
+// ============================================================================
+// 示例实现
+// ============================================================================
+
+static async Task Demo1_BasicUsage(string baseDir)
 {
-    "App": {
-        "Name": "MyApp",
-        "Version": "1.0.0"
-    },
-    "Database": {
-        "ConnectionString": "Server=localhost;Database=mydb",
-        "Timeout": 30
-    },
-    "Logging": {
-        "Level": "Information"
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 1: 基础用法 - JSON 配置与层级覆盖");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    var configPath = Path.Combine(baseDir, "config.json");
+    var localConfigPath = Path.Combine(baseDir, "config.local.json");
+
+    // 创建基础配置
+    File.WriteAllText(configPath, """
+    {
+        "App": {
+            "Name": "MyApp",
+            "Version": "1.0.0",
+            "Debug": false
+        },
+        "Database": {
+            "Host": "localhost",
+            "Port": 3306,
+            "Name": "mydb"
+        }
     }
+    """);
+
+    // 创建本地覆盖配置(高优先级)
+    File.WriteAllText(localConfigPath, """
+    {
+        "App": {
+            "Debug": true
+        },
+        "Database": {
+            "Host": "192.168.1.100"
+        }
+    }
+    """);
+
+    // 构建配置:level 越大优先级越高
+    // 注意:环境变量不可写,所以 isPrimaryWriter 设置在 JSON 配置源上
+    var cfg = new CfgBuilder()
+        .AddJson(configPath, level: 0, writeable: false)
+        .AddJson(localConfigPath, level: 1, writeable: true, isPrimaryWriter: true)
+        .AddEnvironmentVariables(level: 2, prefix: "MYAPP_")
+        .Build();
+
+    // 读取配置
+    Console.WriteLine("1.1 读取配置值:");
+    Console.WriteLine($"    App:Name = {cfg.Get("App:Name")}");
+    Console.WriteLine($"    App:Version = {cfg.Get("App:Version")}");
+    Console.WriteLine($"    App:Debug = {cfg.Get("App:Debug")} (被本地配置覆盖为 true)");
+    Console.WriteLine($"    Database:Host = {cfg.Get("Database:Host")} (被本地配置覆盖)");
+    Console.WriteLine($"    Database:Port = {cfg.Get("Database:Port")}");
+
+    // 检查配置是否存在
+    Console.WriteLine("\n1.2 检查配置是否存在:");
+    Console.WriteLine($"    Exists(App:Name) = {cfg.Exists("App:Name")}");
+    Console.WriteLine($"    Exists(NotExist:Key) = {cfg.Exists("NotExist:Key")}");
+
+    // 修改配置(写入到 isPrimaryWriter 的配置源,需要指定 targetLevel)
+    Console.WriteLine("\n1.3 修改配置:");
+    cfg.Set("App:LastRun", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), targetLevel: 1);
+    await cfg.SaveAsync(targetLevel: 1);
+    Console.WriteLine($"    已设置 App:LastRun = {cfg.Get("App:LastRun")}");
+
+    // 删除配置
+    Console.WriteLine("\n1.4 删除配置:");
+    cfg.Set("App:TempKey", "临时值", targetLevel: 1);
+    Console.WriteLine($"    设置 App:TempKey = {cfg.Get("App:TempKey")}");
+    cfg.Remove("App:TempKey", targetLevel: 1);
+    await cfg.SaveAsync(targetLevel: 1);
+    Console.WriteLine($"    删除后 App:TempKey = {cfg.Get("App:TempKey") ?? "(null)"}");
+
+    // 转换为 Microsoft.Extensions.Configuration
+    Console.WriteLine("\n1.5 转换为 IConfigurationRoot:");
+    var msConfig = cfg.ToMicrosoftConfiguration();
+    Console.WriteLine($"    msConfig[\"App:Name\"] = {msConfig["App:Name"]}");
+
+    cfg.Dispose();
+    File.Delete(configPath);
+    File.Delete(localConfigPath);
+
+    Console.WriteLine("\n[示例 1 完成]\n");
 }
-""");
 
-// 写入本地覆盖配置
-File.WriteAllText(localSettingsPath, """
+static async Task Demo2_MultiFormat(string baseDir)
 {
-    "Database": {
-        "ConnectionString": "Server=192.168.1.100;Database=proddb"
-    },
-    "Logging": {
-        "Level": "Debug"
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 2: 多格式支持 - INI、XML、YAML、TOML");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    // INI 格式
+    var iniPath = Path.Combine(baseDir, "config.ini");
+    File.WriteAllText(iniPath, """
+    [App]
+    Name=IniApp
+    Version=2.0.0
+
+    [Database]
+    Host=ini-server
+    Port=5432
+    """);
+
+    // XML 格式
+    var xmlPath = Path.Combine(baseDir, "config.xml");
+    File.WriteAllText(xmlPath, """
+    <?xml version="1.0" encoding="utf-8"?>
+    <configuration>
+        <App>
+            <Name>XmlApp</Name>
+            <Version>3.0.0</Version>
+        </App>
+        <Database>
+            <Host>xml-server</Host>
+            <Port>1433</Port>
+        </Database>
+    </configuration>
+    """);
+
+    // YAML 格式
+    var yamlPath = Path.Combine(baseDir, "config.yaml");
+    File.WriteAllText(yamlPath, """
+    App:
+      Name: YamlApp
+      Version: 4.0.0
+    Database:
+      Host: yaml-server
+      Port: 27017
+    """);
+
+    // TOML 格式
+    var tomlPath = Path.Combine(baseDir, "config.toml");
+    File.WriteAllText(tomlPath, """
+    [App]
+    Name = "TomlApp"
+    Version = "5.0.0"
+
+    [Database]
+    Host = "toml-server"
+    Port = 6379
+    """);
+
+    // 分别测试各格式
+    Console.WriteLine("2.1 INI 格式:");
+    using (var iniCfg = new CfgBuilder().AddIni(iniPath, level: 0, writeable: true).Build())
+    {
+        Console.WriteLine($"    App:Name = {iniCfg.Get("App:Name")}");
+        Console.WriteLine($"    Database:Port = {iniCfg.Get("Database:Port")}");
+    }
+
+    Console.WriteLine("\n2.2 XML 格式:");
+    using (var xmlCfg = new CfgBuilder().AddXml(xmlPath, level: 0, writeable: true).Build())
+    {
+        Console.WriteLine($"    App:Name = {xmlCfg.Get("App:Name")}");
+        Console.WriteLine($"    Database:Port = {xmlCfg.Get("Database:Port")}");
     }
+
+    Console.WriteLine("\n2.3 YAML 格式:");
+    using (var yamlCfg = new CfgBuilder().AddYaml(yamlPath, level: 0, writeable: true).Build())
+    {
+        Console.WriteLine($"    App:Name = {yamlCfg.Get("App:Name")}");
+        Console.WriteLine($"    Database:Port = {yamlCfg.Get("Database:Port")}");
+    }
+
+    Console.WriteLine("\n2.4 TOML 格式:");
+    using (var tomlCfg = new CfgBuilder().AddToml(tomlPath, level: 0, writeable: true).Build())
+    {
+        Console.WriteLine($"    App:Name = {tomlCfg.Get("App:Name")}");
+        Console.WriteLine($"    Database:Port = {tomlCfg.Get("Database:Port")}");
+    }
+
+    // 混合多种格式
+    Console.WriteLine("\n2.5 混合多种格式(层级覆盖):");
+    using var mixedCfg = new CfgBuilder()
+        .AddIni(iniPath, level: 0, writeable: false)
+        .AddYaml(yamlPath, level: 1, writeable: false)
+        .AddToml(tomlPath, level: 2, writeable: true, isPrimaryWriter: true)
+        .Build();
+
+    Console.WriteLine($"    App:Name = {mixedCfg.Get("App:Name")} (来自 TOML,最高优先级)");
+    Console.WriteLine($"    App:Version = {mixedCfg.Get("App:Version")} (来自 TOML)");
+
+    File.Delete(iniPath);
+    File.Delete(xmlPath);
+    File.Delete(yamlPath);
+    File.Delete(tomlPath);
+
+    Console.WriteLine("\n[示例 2 完成]\n");
+    await Task.CompletedTask;
 }
-""");
-
-// 构建配置
-var cfg = new CfgBuilder()
-    .AddJson(appSettingsPath, level: 0, writeable: false)
-    .AddJson(localSettingsPath, level: 1, writeable: true, isPrimaryWriter: true)
-    .AddEnvironmentVariables(level: 2, prefix: "APP_")
-    .Build();
-
-// 读取配置
-Console.WriteLine("1. 读取配置值:");
-Console.WriteLine($"   App:Name = {cfg.Get("App:Name")}");
-Console.WriteLine($"   App:Version = {cfg.Get("App:Version")}");
-Console.WriteLine($"   Database:ConnectionString = {cfg.Get("Database:ConnectionString")}");
-Console.WriteLine($"   Database:Timeout = {cfg.Get<int>("Database:Timeout")}");
-Console.WriteLine($"   Logging:Level = {cfg.Get("Logging:Level")} (被本地配置覆盖)");
-
-// 检查配置是否存在
-Console.WriteLine("\n2. 检查配置是否存在:");
-Console.WriteLine($"   Exists(App:Name) = {cfg.Exists("App:Name")}");
-Console.WriteLine($"   Exists(NotExist:Key) = {cfg.Exists("NotExist:Key")}");
-
-// 修改配置
-Console.WriteLine("\n3. 修改配置:");
-cfg.Set("App:LastRun", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
-await cfg.SaveAsync();
-Console.WriteLine($"   已设置 App:LastRun = {cfg.Get("App:LastRun")}");
-
-// 转换为 Microsoft.Extensions.Configuration
-Console.WriteLine("\n4. 转换为 IConfigurationRoot:");
-var msConfig = cfg.ToMicrosoftConfiguration();
-Console.WriteLine($"   msConfig[\"App:Name\"] = {msConfig["App:Name"]}");
-
-// 清理
-cfg.Dispose();
-File.Delete(appSettingsPath);
-File.Delete(localSettingsPath);
-
-Console.WriteLine("\n=== 示例完成 ===");
+
+static async Task Demo3_ConfigSection(string baseDir)
+{
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 3: 配置节 (GetSection) 与子键枚举");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    var configPath = Path.Combine(baseDir, "section-demo.json");
+    File.WriteAllText(configPath, """
+    {
+        "Database": {
+            "Primary": {
+                "Host": "primary.db.local",
+                "Port": 3306,
+                "Username": "admin"
+            },
+            "Replica": {
+                "Host": "replica.db.local",
+                "Port": 3307,
+                "Username": "reader"
+            }
+        },
+        "Cache": {
+            "Redis": {
+                "Host": "redis.local",
+                "Port": 6379
+            }
+        }
+    }
+    """);
+
+    using var cfg = new CfgBuilder()
+        .AddJson(configPath, level: 0, writeable: true, isPrimaryWriter: true)
+        .Build();
+
+    // 获取配置节
+    Console.WriteLine("3.1 使用 GetSection 简化嵌套访问:");
+    var dbSection = cfg.GetSection("Database");
+    var primarySection = dbSection.GetSection("Primary");
+
+    Console.WriteLine($"    Database:Primary:Host = {primarySection.Get("Host")}");
+    Console.WriteLine($"    Database:Primary:Port = {primarySection.Get<int>("Port")}");
+
+    // 枚举子键
+    Console.WriteLine("\n3.2 枚举配置节的子键:");
+    Console.WriteLine("    Database 的子键:");
+    foreach (var key in dbSection.GetChildKeys())
+    {
+        Console.WriteLine($"      - {key}");
+    }
+
+    Console.WriteLine("\n    顶级配置键:");
+    foreach (var key in cfg.GetChildKeys())
+    {
+        Console.WriteLine($"      - {key}");
+    }
+
+    // 通过配置节修改值
+    Console.WriteLine("\n3.3 通过配置节修改值:");
+    var replicaSection = dbSection.GetSection("Replica");
+    replicaSection.Set("Port", "3308");
+    await cfg.SaveAsync();
+    Console.WriteLine($"    修改后 Database:Replica:Port = {replicaSection.Get("Port")}");
+
+    File.Delete(configPath);
+
+    Console.WriteLine("\n[示例 3 完成]\n");
+}
+
+static async Task Demo4_BatchOperations(string baseDir)
+{
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 4: 批量操作 - GetMany / SetMany");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    var configPath = Path.Combine(baseDir, "batch-demo.json");
+    File.WriteAllText(configPath, """
+    {
+        "Settings": {
+            "Theme": "dark",
+            "Language": "zh-CN",
+            "FontSize": "14",
+            "AutoSave": "true"
+        }
+    }
+    """);
+
+    using var cfg = new CfgBuilder()
+        .AddJson(configPath, level: 0, writeable: true, isPrimaryWriter: true)
+        .Build();
+
+    // 批量获取
+    Console.WriteLine("4.1 批量获取 (GetMany):");
+    var keys = new[] { "Settings:Theme", "Settings:Language", "Settings:FontSize" };
+    var values = cfg.GetMany(keys);
+    foreach (var kv in values)
+    {
+        Console.WriteLine($"    {kv.Key} = {kv.Value}");
+    }
+
+    // 批量获取并转换类型
+    Console.WriteLine("\n4.2 批量获取并转换类型 (GetMany<T>):");
+    var intKeys = new[] { "Settings:FontSize" };
+    var intValues = cfg.GetMany<int>(intKeys);
+    foreach (var kv in intValues)
+    {
+        Console.WriteLine($"    {kv.Key} = {kv.Value} (int)");
+    }
+
+    // 批量设置
+    Console.WriteLine("\n4.3 批量设置 (SetMany):");
+    var newValues = new Dictionary<string, string?>
+    {
+        ["Settings:Theme"] = "light",
+        ["Settings:FontSize"] = "16",
+        ["Settings:NewOption"] = "enabled"
+    };
+    cfg.SetMany(newValues);
+    await cfg.SaveAsync();
+
+    Console.WriteLine("    批量设置后的值:");
+    var updatedValues = cfg.GetMany(new[] { "Settings:Theme", "Settings:FontSize", "Settings:NewOption" });
+    foreach (var kv in updatedValues)
+    {
+        Console.WriteLine($"    {kv.Key} = {kv.Value}");
+    }
+
+    File.Delete(configPath);
+
+    Console.WriteLine("\n[示例 4 完成]\n");
+}
+
+static async Task Demo5_TypeConversion(string baseDir)
+{
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 5: 类型转换");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    var configPath = Path.Combine(baseDir, "types-demo.json");
+    File.WriteAllText(configPath, """
+    {
+        "Types": {
+            "IntValue": "42",
+            "LongValue": "9223372036854775807",
+            "DoubleValue": "3.14159",
+            "DecimalValue": "123.456",
+            "BoolTrue": "true",
+            "BoolFalse": "false",
+            "DateValue": "2024-12-25",
+            "GuidValue": "550e8400-e29b-41d4-a716-446655440000",
+            "EnumValue": "Warning"
+        }
+    }
+    """);
+
+    using var cfg = new CfgBuilder()
+        .AddJson(configPath, level: 0, writeable: false)
+        .Build();
+
+    Console.WriteLine("5.1 各种类型转换:");
+    Console.WriteLine($"    int: {cfg.Get<int>("Types:IntValue")}");
+    Console.WriteLine($"    long: {cfg.Get<long>("Types:LongValue")}");
+    Console.WriteLine($"    double: {cfg.Get<double>("Types:DoubleValue")}");
+    Console.WriteLine($"    decimal: {cfg.Get<decimal>("Types:DecimalValue")}");
+    Console.WriteLine($"    bool (true): {cfg.Get<bool>("Types:BoolTrue")}");
+    Console.WriteLine($"    bool (false): {cfg.Get<bool>("Types:BoolFalse")}");
+    Console.WriteLine($"    DateTime: {cfg.Get<DateTime>("Types:DateValue"):yyyy-MM-dd}");
+    Console.WriteLine($"    Guid: {cfg.Get<Guid>("Types:GuidValue")}");
+    Console.WriteLine($"    Enum: {cfg.Get<LogLevel>("Types:EnumValue")}");
+
+    Console.WriteLine("\n5.2 可空类型与默认值:");
+    Console.WriteLine($"    不存在的键 (int?): {cfg.Get<int?>("Types:NotExist") ?? -1}");
+    Console.WriteLine($"    不存在的键 (string): {cfg.Get("Types:NotExist") ?? "(null)"}");
+
+    File.Delete(configPath);
+
+    Console.WriteLine("\n[示例 5 完成]\n");
+    await Task.CompletedTask;
+}
+
+static async Task Demo6_DynamicReload(string baseDir)
+{
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 6: 动态配置重载");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    var configPath = Path.Combine(baseDir, "reload-demo.json");
+    File.WriteAllText(configPath, """
+    {
+        "App": {
+            "RefreshInterval": "30"
+        }
+    }
+    """);
+
+    // 启用 reloadOnChange
+    var cfg = new CfgBuilder()
+        .AddJson(configPath, level: 0, writeable: true, isPrimaryWriter: true, reloadOnChange: true)
+        .Build();
+
+    Console.WriteLine("6.1 配置动态重载选项:");
+    var msConfig = cfg.ToMicrosoftConfiguration(new DynamicReloadOptions
+    {
+        DebounceMs = 100,                    // 防抖时间
+        EnableDynamicReload = true,          // 启用动态重载
+        Strategy = ReloadStrategy.Eager,     // 立即重载
+        RollbackOnError = true,              // 错误时回滚
+        HistorySize = 5                      // 保留 5 条历史
+    });
+    Console.WriteLine("    已配置: DebounceMs=100, Strategy=Eager, HistorySize=5");
+
+    // 使用 IChangeToken 监听变更
+    Console.WriteLine("\n6.2 使用 IChangeToken 监听变更:");
+    var changeCount = 0;
+    ChangeToken.OnChange(
+        () => msConfig.GetReloadToken(),
+        () =>
+        {
+            changeCount++;
+            Console.WriteLine($"    [IChangeToken] 配置已更新 (第 {changeCount} 次)");
+        });
+    Console.WriteLine("    已注册 IChangeToken 回调");
+
+    // 使用 Rx 订阅配置变更
+    Console.WriteLine("\n6.3 使用 Rx 订阅配置变更:");
+    using var subscription = cfg.ConfigChanges.Subscribe(e =>
+    {
+        Console.WriteLine($"    [Rx] 批次 {e.BatchId} - {e.Changes.Count} 个变更:");
+        foreach (var (key, change) in e.Changes)
+        {
+            Console.WriteLine($"         [{change.Type}] {key}: {change.OldValue} -> {change.NewValue}");
+        }
+    });
+    Console.WriteLine("    已订阅 ConfigChanges");
+
+    // 模拟配置变更
+    Console.WriteLine("\n6.4 模拟配置变更:");
+    Console.WriteLine("    修改 App:RefreshInterval 为 60...");
+    cfg.Set("App:RefreshInterval", "60");
+    await cfg.SaveAsync();
+
+    // 等待变更通知
+    await Task.Delay(200);
+
+    Console.WriteLine($"\n    当前值: App:RefreshInterval = {cfg.Get("App:RefreshInterval")}");
+
+    cfg.Dispose();
+    File.Delete(configPath);
+
+    Console.WriteLine("\n[示例 6 完成]\n");
+}
+
+static async Task Demo7_DependencyInjection(string baseDir)
+{
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 7: 依赖注入集成");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    var configPath = Path.Combine(baseDir, "di-demo.json");
+    File.WriteAllText(configPath, """
+    {
+        "Database": {
+            "Host": "db.example.com",
+            "Port": "5432",
+            "Name": "production"
+        },
+        "Logging": {
+            "Level": "Information",
+            "EnableConsole": "true"
+        }
+    }
+    """);
+
+    // 配置服务容器
+    var services = new ServiceCollection();
+
+    // 方式1: 使用 AddApqCfg 注册配置
+    Console.WriteLine("7.1 注册 Apq.Cfg 到 DI 容器:");
+    services.AddApqCfg(cfg => cfg
+        .AddJson(configPath, level: 0, writeable: true, isPrimaryWriter: true));
+    Console.WriteLine("    已注册 ICfgRoot 和 IConfigurationRoot");
+
+    // 方式2: 绑定强类型配置
+    Console.WriteLine("\n7.2 绑定强类型配置:");
+    services.ConfigureApqCfg<DatabaseOptions>("Database");
+    services.ConfigureApqCfg<LoggingOptions>("Logging");
+    Console.WriteLine("    已绑定 DatabaseOptions 和 LoggingOptions");
+
+    // 构建服务提供者
+    var provider = services.BuildServiceProvider();
+
+    // 获取服务
+    Console.WriteLine("\n7.3 从 DI 容器获取服务:");
+    var cfgRoot = provider.GetRequiredService<ICfgRoot>();
+    var msConfig = provider.GetRequiredService<IConfigurationRoot>();
+    var dbOptions = provider.GetRequiredService<IOptions<DatabaseOptions>>().Value;
+    var logOptions = provider.GetRequiredService<IOptions<LoggingOptions>>().Value;
+
+    Console.WriteLine($"    ICfgRoot: Database:Host = {cfgRoot.Get("Database:Host")}");
+    Console.WriteLine($"    IConfigurationRoot: Database:Host = {msConfig["Database:Host"]}");
+    Console.WriteLine($"    DatabaseOptions: Host={dbOptions.Host}, Port={dbOptions.Port}, Name={dbOptions.Name}");
+    Console.WriteLine($"    LoggingOptions: Level={logOptions.Level}, EnableConsole={logOptions.EnableConsole}");
+
+    // 清理
+    if (provider is IDisposable disposable)
+        disposable.Dispose();
+    File.Delete(configPath);
+
+    Console.WriteLine("\n[示例 7 完成]\n");
+    await Task.CompletedTask;
+}
+
+static async Task Demo8_EncodingMapping(string baseDir)
+{
+    Console.WriteLine("═══════════════════════════════════════════════════════════════");
+    Console.WriteLine("示例 8: 编码映射配置");
+    Console.WriteLine("═══════════════════════════════════════════════════════════════\n");
+
+    var configPath = Path.Combine(baseDir, "encoding-demo.json");
+    File.WriteAllText(configPath, """
+    {
+        "App": {
+            "Name": "编码测试应用",
+            "Description": "支持中文和特殊字符: äöü ñ 日本語"
+        }
+    }
+    """, Encoding.UTF8);
+
+    Console.WriteLine("8.1 编码检测置信度阈值:");
+    var cfg1 = new CfgBuilder()
+        .WithEncodingConfidenceThreshold(0.7f)
+        .AddJson(configPath, level: 0, writeable: false)
+        .Build();
+    Console.WriteLine($"    置信度阈值设置为 0.7");
+    Console.WriteLine($"    App:Name = {cfg1.Get("App:Name")}");
+    cfg1.Dispose();
+
+    Console.WriteLine("\n8.2 编码检测日志:");
+    var cfg2 = new CfgBuilder()
+        .WithEncodingDetectionLogging(result =>
+        {
+            Console.WriteLine($"    [编码检测] 文件: {Path.GetFileName(result.FilePath)}");
+            Console.WriteLine($"               编码: {result.Encoding.EncodingName}");
+            Console.WriteLine($"               置信度: {result.Confidence:P0}");
+            Console.WriteLine($"               方法: {result.Method}");
+        })
+        .AddJson(configPath, level: 0, writeable: false)
+        .Build();
+    cfg2.Dispose();
+
+    Console.WriteLine("\n8.3 编码映射规则:");
+    Console.WriteLine("    支持三种映射方式:");
+    Console.WriteLine("    - 完整路径: AddReadEncodingMapping(path, encoding)");
+    Console.WriteLine("    - 通配符:   AddReadEncodingMappingWildcard(\"*.json\", encoding)");
+    Console.WriteLine("    - 正则:     AddReadEncodingMappingRegex(@\"config.*\\.json$\", encoding)");
+
+    // 演示编码映射配置
+    var cfg3 = new CfgBuilder()
+        // 为特定文件指定编码
+        .AddReadEncodingMapping(configPath, Encoding.UTF8, priority: 100)
+        // 为所有 JSON 文件指定写入编码
+        .AddWriteEncodingMappingWildcard("*.json", new UTF8Encoding(false), priority: 50)
+        .AddJson(configPath, level: 0, writeable: false)
+        .Build();
+    Console.WriteLine("\n    已配置编码映射规则");
+    Console.WriteLine($"    App:Description = {cfg3.Get("App:Description")}");
+    cfg3.Dispose();
+
+    File.Delete(configPath);
+
+    Console.WriteLine("\n[示例 8 完成]\n");
+    await Task.CompletedTask;
+}
+
+// ============================================================================
+// 强类型配置类
+// ============================================================================
+
+public class DatabaseOptions
+{
+    public string? Host { get; set; }
+    public int Port { get; set; }
+    public string? Name { get; set; }
+}
+
+public class LoggingOptions
+{
+    public string? Level { get; set; }
+    public bool EnableConsole { get; set; }
+}
+
+// 用于类型转换示例的枚举
+public enum LogLevel { Debug, Info, Warning, Error }

+ 1 - 1
docs/IMPROVEMENTS.md

@@ -18,7 +18,7 @@
 ```csharp
 // 示例:依赖注入支持
 services.AddApqCfg(cfg => cfg
-    .AddJson("appsettings.json", level: 0)
+    .AddJson("config.json", level: 0)
     .AddEnvironmentVariables(level: 1)
     .WithValidation<AppSettings>());
 ```

+ 2 - 2
docs/动态配置重载设计方案.md

@@ -447,8 +447,8 @@ public sealed class ConfigChangeEvent
 ```csharp
 // 构建配置
 var cfg = new CfgBuilder()
-    .AddJson("appsettings.json", level: 1, writeable: false, reloadOnChange: true)
-    .AddJson("appsettings.local.json", level: 2, writeable: true, reloadOnChange: true)
+    .AddJson("config.json", level: 1, writeable: false, reloadOnChange: true)
+    .AddJson("config.local.json", level: 2, writeable: true, reloadOnChange: true)
     .AddEnvironmentVariables(level: 3)
     .Build();