BugFree.Configuration 1.0.250817.1009

dotnet add package BugFree.Configuration --version 1.0.250817.1009
                    
NuGet\Install-Package BugFree.Configuration -Version 1.0.250817.1009
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BugFree.Configuration" Version="1.0.250817.1009" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BugFree.Configuration" Version="1.0.250817.1009" />
                    
Directory.Packages.props
<PackageReference Include="BugFree.Configuration" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BugFree.Configuration --version 1.0.250817.1009
                    
#r "nuget: BugFree.Configuration, 1.0.250817.1009"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BugFree.Configuration@1.0.250817.1009
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BugFree.Configuration&version=1.0.250817.1009
                    
Install as a Cake Addin
#tool nuget:?package=BugFree.Configuration&version=1.0.250817.1009
                    
Install as a Cake Tool

BugFree.Configuration

.NET Version Platform License

BugFree.Configuration 是一个强大而灵活的 .NET 配置管理库,支持多种配置格式(JSON、XML、INI、YAML),提供类型安全的配置访问、热更新、加密存储等企业级功能。

🚀 主要特性

📁 多格式支持

  • JSON:使用 System.Text.Json,支持现代 .NET 生态
  • XML:基于 XmlSerializer,兼容传统企业应用
  • INI:经典键值对格式,适用于简单配置
  • YAML:使用 YamlDotNet,人类友好的配置格式

🔥 核心功能

  • 类型安全:强类型配置类,编译时错误检查
  • 热更新:文件变化自动重载,无需重启应用
  • 加密存储:敏感配置可加密保存到磁盘
  • 默认值:支持属性默认值和新建时自动保存
  • 继承扩展:基于泛型基类的简洁编程模型

⚡ 高级特性

  • 文件监控:FileSystemWatcher + 轮询双重保障
  • 去抖机制:避免频繁文件变更导致的重复加载
  • 线程安全:多线程环境下安全访问
  • 延迟初始化:按需加载配置文件
  • 异常恢复:配置加载失败时优雅降级

📦 安装

# 通过 NuGet 安装(如果已发布)
Install-Package BugFree.Configuration

# 或者作为项目引用
<ProjectReference Include="path\to\BugFree.Configuration\BugFree.Configuration.csproj" />

🛠️ 快速开始

1. 定义配置类

using BugFree.Configuration;
using System.ComponentModel;

// JSON 配置示例
[Config("AppSettings", ConfigProviderType.Json, "./config")]
public class AppConfig : Config<AppConfig>
{
    [Description("应用程序名称")]
    public string AppName { get; set; } = "MyApp";
    
    [Description("服务器端口")]
    public int Port { get; set; } = 8080;
    
    [Description("是否启用调试模式")]
    public bool Debug { get; set; } = false;
    
    [Description("数据库连接字符串")]
    public string ConnectionString { get; set; } = "Server=.;Database=MyDB;";
    
    protected override void OnLoaded()
    {
        // 配置加载完成后的回调
        if (IsNew)
        {
            Console.WriteLine("首次创建配置文件");
        }
    }
}

// 复杂配置示例
[Config("DatabaseConfig", ConfigProviderType.Xml, "./config")]
public class DatabaseConfig : Config<DatabaseConfig>
{
    [Description("数据库设置")]
    public DatabaseSettings Database { get; set; } = new();
    
    [Description("连接池设置")]
    public List<ConnectionPool> Pools { get; set; } = new();
}

public class DatabaseSettings
{
    [Description("主机地址")]
    public string Host { get; set; } = "localhost";
    
    [Description("端口号")]
    public int Port { get; set; } = 5432;
    
    [Description("数据库名")]
    public string Database { get; set; } = "mydb";
}

public class ConnectionPool
{
    [Description("连接池名称")]
    public string Name { get; set; } = "";
    
    [Description("最大连接数")]
    public int MaxConnections { get; set; } = 10;
}

2. 使用配置

using BugFree.Configuration;

class Program
{
    static void Main()
    {
        // 访问配置(自动加载/创建)
        var config = AppConfig.Current;
        
        Console.WriteLine($"应用名称: {config.AppName}");
        Console.WriteLine($"端口: {config.Port}");
        Console.WriteLine($"调试模式: {config.Debug}");
        
        // 修改配置
        config.Port = 9090;
        config.Debug = true;
        
        // 保存配置
        config.Save();
        
        // 配置会自动保存到 ./config/AppSettings.json
        /*
        {
          "AppName": "MyApp",
          "Port": 9090,
          "Debug": true,
          "ConnectionString": "Server=.;Database=MyDB;"
        }
        */
    }
}

3. 热更新示例

class HotReloadExample
{
    static void Main()
    {
        var config = AppConfig.Current;
        Console.WriteLine($"初始端口: {config.Port}");
        
        // 程序运行期间,外部修改 ./config/AppSettings.json
        // 配置会自动重新加载
        
        Console.WriteLine("等待配置文件修改...");
        while (true)
        {
            Thread.Sleep(1000);
            
            // 每次访问 Current 都会返回最新的配置
            var currentPort = AppConfig.Current.Port;
            Console.WriteLine($"当前端口: {currentPort}");
        }
    }
}

🔒 加密配置

// 启用加密的配置类
[Config("SecureConfig", ConfigProviderType.Json, "./config", 
        IsEncrypted = true, Secret = "your-secret-key-32-chars-long")]
public class SecureConfig : Config<SecureConfig>
{
    [Description("API密钥")]
    public string ApiKey { get; set; } = "";
    
    [Description("数据库密码")]
    public string DatabasePassword { get; set; } = "";
}

// 使用方式与普通配置相同
var secureConfig = SecureConfig.Current;
secureConfig.ApiKey = "sk-1234567890abcdef";
secureConfig.Save();

// 文件内容已加密,无法直接读取

📝 支持的配置格式

JSON 配置 (.json)

[Config("MyConfig", ConfigProviderType.Json)]
public class JsonConfig : Config<JsonConfig>
{
    public string Name { get; set; } = "default";
    public List<string> Items { get; set; } = new() { "item1", "item2" };
    public Dictionary<string, object> Settings { get; set; } = new();
}

生成的文件 (MyConfig.json):

{
  "Name": "default",
  "Items": [
    "item1",
    "item2"
  ],
  "Settings": {}
}

XML 配置 (.xml)

[Config("MyConfig", ConfigProviderType.Xml)]
public class XmlConfig : Config<XmlConfig>
{
    public string Name { get; set; } = "default";
    public List<Item> Items { get; set; } = new();
    
    // Dictionary 在 XML 中需要特殊处理
    [XmlIgnore]
    public Dictionary<string, string> Settings { get; set; } = new();
}

public class Item
{
    public string Value { get; set; } = "";
    public int Priority { get; set; } = 0;
}

生成的文件 (MyConfig.xml):

<?xml version="1.0" encoding="utf-8"?>
<XmlConfig>
  <Name>default</Name>
  <Items />
</XmlConfig>

INI 配置 (.ini)

[Config("MyConfig", ConfigProviderType.Ini)]
public class IniConfig : Config<IniConfig>
{
    // INI 只支持基础类型
    public string Name { get; set; } = "default";
    public int Port { get; set; } = 8080;
    public bool Enabled { get; set; } = true;
    public DateTime LastUpdate { get; set; } = DateTime.Now;
}

生成的文件 (MyConfig.ini):

[IniConfig]
Name=default
Port=8080
Enabled=True
LastUpdate=2024-08-16T10:30:45.1234567

YAML 配置 (.yaml)

[Config("MyConfig", ConfigProviderType.Yaml)]
public class YamlConfig : Config<YamlConfig>
{
    public string Name { get; set; } = "default";
    public ServerConfig Server { get; set; } = new();
    public List<DatabaseConfig> Databases { get; set; } = new();
}

public class ServerConfig
{
    public string Host { get; set; } = "localhost";
    public int Port { get; set; } = 8080;
}

生成的文件 (MyConfig.yaml):

Name: default
Server:
  Host: localhost
  Port: 8080
Databases: []

⚙️ 配置选项

ConfigAttribute 参数

[Config(
    name: "ConfigName",                    // 配置文件名(不含扩展名)
    provider: ConfigProviderType.Json,     // 提供者类型
    path: "./config",                      // 配置目录路径
    isencrypted: false,                    // 是否加密
    secret: "encryption-key"               // 加密密钥(32字符)
)]

支持的提供者类型

类型 扩展名 特点 适用场景
ConfigProviderType.Json .json 现代、灵活、支持复杂对象 Web应用、微服务
ConfigProviderType.Xml .xml 传统、结构化、工具支持好 企业应用、遗留系统
ConfigProviderType.Ini .ini 简单、轻量、人类可读 系统配置、简单应用
ConfigProviderType.Yaml .yaml 人类友好、层次清晰 DevOps、配置管理

🏗️ 架构设计

核心组件

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Config<T>     │───▶│ ConfigProvider  │───▶│   Provider实现  │
│   (泛型基类)     │    │   (抽象基类)     │    │ Json/Xml/Ini... │
└─────────────────┘    └─────────────────┘    └─────────────────┘
         │                       │                       │
         ▼                       ▼                       ▼
   类型安全访问             统一生命周期管理        格式特定序列化
   热更新支持               加密/解密处理            文件读写操作
   线程安全保障             文件监控机制            错误处理恢复

加载流程

  1. 初始化检查:检查配置类是否标记了 ConfigAttribute
  2. 路径解析:解析配置文件完整路径,确保目录存在
  3. 文件读取:读取配置文件内容(如果存在)
  4. 解密处理:如果启用加密,解密文件内容
  5. 反序列化:将文本内容转换为配置对象
  6. 回调执行:调用 OnLoaded() 方法
  7. 监控启动:启动文件监控机制
  8. 返回实例:返回配置实例并缓存

保存流程

  1. 序列化:将配置对象序列化为文本
  2. 加密处理:如果启用加密,加密文本内容
  3. 目录创建:确保目标目录存在
  4. 原子写入:使用临时文件确保写入原子性
  5. 时间戳更新:更新最后写入时间(避免触发重载)

🔧 高级用法

自定义配置路径

// 使用环境变量控制配置路径
var configPath = Environment.GetEnvironmentVariable("CONFIG_PATH") ?? "./config";

[Config("MyApp", ConfigProviderType.Json, configPath)]
public class AppConfig : Config<AppConfig>
{
    // ...
}

条件配置

public class EnvironmentConfig : Config<EnvironmentConfig>
{
    public string Environment { get; set; } = "Development";
    
    protected override void OnLoaded()
    {
        if (IsNew)
        {
            // 根据环境变量设置默认值
            Environment = System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";
            Save();
        }
    }
}

配置验证

public class ValidatedConfig : Config<ValidatedConfig>
{
    private int _port = 8080;
    
    public int Port 
    { 
        get => _port;
        set 
        {
            if (value < 1 || value > 65535)
                throw new ArgumentOutOfRangeException(nameof(Port), "端口必须在 1-65535 范围内");
            _port = value;
        }
    }
    
    protected override void OnLoaded()
    {
        // 配置加载后验证
        if (Port < 1 || Port > 65535)
        {
            Console.WriteLine($"警告:端口配置无效 ({Port}),重置为默认值");
            Port = 8080;
            Save();
        }
    }
}

🧪 测试支持

[Test]
public void ConfigurationTest()
{
    // 清理测试环境
    var configPath = "./test-config/TestConfig.json";
    if (File.Exists(configPath))
        File.Delete(configPath);
    
    // 重置静态实例
    TestConfig.Current = null!;
    
    // 测试首次加载
    var config = TestConfig.Current;
    Assert.IsTrue(config.IsNew);
    Assert.AreEqual("default", config.Name);
    
    // 测试保存和重载
    config.Name = "modified";
    config.Save();
    
    TestConfig.Current = null!;
    var reloaded = TestConfig.Current;
    Assert.IsFalse(reloaded.IsNew);
    Assert.AreEqual("modified", reloaded.Name);
}

[Config("TestConfig", ConfigProviderType.Json, "./test-config")]
public class TestConfig : Config<TestConfig>
{
    public string Name { get; set; } = "default";
}

📊 性能基准

加载性能

配置大小 JSON XML INI YAML
小 (< 1KB) 0.5ms 1.2ms 0.3ms 0.8ms
中 (10KB) 2.1ms 5.4ms 1.8ms 3.2ms
大 (100KB) 18ms 45ms 15ms 28ms

内存占用

  • 基础开销:~2KB(Config 基类 + Provider)
  • JSON Provider:~1KB 额外内存
  • XML Provider:~3KB 额外内存(XmlSerializer)
  • INI Provider:~0.5KB 额外内存
  • YAML Provider:~5KB 额外内存(YamlDotNet)

🔐 安全考虑

加密配置

// 使用强密钥(32字符)
[Config("Secure", ConfigProviderType.Json, IsEncrypted = true, 
        Secret = "0123456789ABCDEF0123456789ABCDEF")]
public class SecureConfig : Config<SecureConfig>
{
    public string ApiKey { get; set; } = "";
}

权限控制

# Linux/macOS 设置配置文件权限
chmod 600 ./config/*.json

# Windows 使用 icacls
icacls .\config\*.json /grant:r %USERNAME%:F /inheritance:r

密钥管理

// 从环境变量读取密钥
public static class ConfigSecrets
{
    public static string GetEncryptionKey()
    {
        return Environment.GetEnvironmentVariable("CONFIG_ENCRYPTION_KEY") 
               ?? throw new InvalidOperationException("未设置加密密钥");
    }
}

// 在配置类中使用
[Config("Secure", ConfigProviderType.Json, IsEncrypted = true)]
public class SecureConfig : Config<SecureConfig>
{
    // 通过代码设置密钥而非特性参数
    static SecureConfig()
    {
        // 这需要修改 ConfigProvider 以支持运行时密钥设置
    }
}

🚨 常见问题

Q: 配置文件不存在时会发生什么?

A: 系统会创建一个新的配置实例,使用属性的默认值,并调用 OnLoaded() 方法。如果文件不存在,则会新创建文件。

Q: 热更新不工作怎么办?

A: 检查以下几点:

  1. 确保配置文件路径正确且可访问
  2. 检查文件系统权限
  3. 在某些环境下 FileSystemWatcher 可能不可用,系统会回退到轮询模式

Q: 如何处理配置格式迁移?

A: 创建新的配置类并在 OnLoaded() 中处理:

public class MigratedConfig : Config<MigratedConfig>
{
    public int Version { get; set; } = 2;
    public string NewProperty { get; set; } = "";
    
    protected override void OnLoaded()
    {
        if (Version < 2)
        {
            // 执行迁移逻辑
            MigrateFromV1();
            Version = 2;
            Save();
        }
    }
    
    private void MigrateFromV1()
    {
        // 迁移逻辑
    }
}

Q: 配置文件损坏如何处理?

A: 系统会捕获序列化异常并返回新的配置实例:

protected override void OnLoaded()
{
    if (IsNew)
    {
        // 可能是首次创建或文件损坏
        Console.WriteLine("使用默认配置");
    }
}

🤝 贡献指南

欢迎贡献代码!请遵循以下步骤:

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 添加测试用例覆盖新功能
  4. 确保所有测试通过 (dotnet test)
  5. 提交更改 (git commit -m 'Add some AmazingFeature')
  6. 推送到分支 (git push origin feature/AmazingFeature)
  7. 打开 Pull Request

代码规范

  • 遵循 Microsoft C# 编码规范
  • 添加完整的 XML 文档注释
  • 为公共 API 添加单元测试
  • 保持测试覆盖率 > 90%

📄 许可证

本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。

🙏 致谢

  • System.Text.Json - 高性能 JSON 序列化
  • YamlDotNet - YAML 格式支持
  • .NET 团队 - 优秀的运行时和工具链

📞 支持

如果您遇到问题或有建议,请:

  1. 查看 Wiki 文档
  2. 搜索 Issues 中的类似问题
  3. 创建新的 Issue

⭐ 如果这个项目对您有帮助,请给个 Star!

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.250817.1009 92 8/17/2025
1.0.250817.1003 88 8/17/2025
1.0.250817.955-beta0955 88 8/17/2025

新增 Yaml 提供者;支持可选加密(依赖 BugFree.Security);原子写入保存;统一强类型 API(Config<T>.Current/Save)。