Skip to content

配置快照导出

Apq.Cfg 提供了配置快照导出功能,支持将当前配置状态导出为多种格式,便于调试、备份和迁移。

基本用法

导出为 JSON

csharp
using Apq.Cfg;
using Apq.Cfg.Snapshot;

var cfg = new CfgBuilder()
    .AddJsonFile("config.json", level: 0, writeable: false)
    .Build();

// 导出为 JSON(默认格式)
var json = cfg.ExportSnapshot();

// 导出为格式化的 JSON
var jsonIndented = cfg.ExportSnapshotAsJson(indented: true);

导出为环境变量格式

csharp
// 导出为环境变量格式
var env = cfg.ExportSnapshotAsEnv();
// 输出: APP__NAME=MyApp
//       DATABASE__HOST=localhost

// 添加前缀
var envWithPrefix = cfg.ExportSnapshotAsEnv(prefix: "MYAPP_");
// 输出: MYAPP_APP__NAME=MyApp
//       MYAPP_DATABASE__HOST=localhost

导出为字典

csharp
// 导出为扁平化字典
var dict = cfg.ExportSnapshotAsDictionary();

foreach (var (key, value) in dict)
{
    Console.WriteLine($"{key} = {value}");
}
// 输出: App:Name = MyApp
//       Database:Host = localhost

导出选项

使用 ExportOptions 类自定义导出行为:

csharp
var options = new ExportOptions
{
    // 是否缩进格式化(仅 JSON)
    Indented = true,

    // 是否包含元数据(导出时间、键数量等)
    IncludeMetadata = true,

    // 是否对敏感值进行脱敏
    MaskSensitiveValues = true,

    // 仅包含指定的键(支持通配符 *)
    IncludeKeys = new[] { "App:*", "Database:Host" },

    // 排除指定的键(支持通配符 *)
    ExcludeKeys = new[] { "Secrets:*", "Database:Password" },

    // 环境变量格式的键前缀
    EnvPrefix = "MYAPP_"
};

// 使用内置导出器导出
var json = cfg.ExportSnapshot(SnapshotExporters.Json, options);
var env = cfg.ExportSnapshot(SnapshotExporters.Env, options);

使用构建器模式

csharp
var json = cfg.ExportSnapshot(options =>
{
    options.IncludeMetadata = true;
    options.ExcludeKeys = new[] { "Secrets:*" };
});

导出格式

JSON 格式

导出为嵌套的 JSON 结构:

json
{
  "App": {
    "Name": "MyApp",
    "Version": "1.0.0"
  },
  "Database": {
    "Host": "localhost",
    "Port": "5432"
  }
}

启用元数据后:

json
{
  "App": {
    "Name": "MyApp"
  },
  "__metadata": {
    "exportedAt": "2026-01-02T10:30:00.0000000Z",
    "format": "Apq.Cfg.Snapshot",
    "version": "1.0",
    "keyCount": 5
  }
}

KeyValue 格式

导出为扁平的键值对格式:

App:Name=MyApp
App:Version=1.0.0
Database:Host=localhost
Database:Port=5432

Env 格式

导出为环境变量格式(键名转换为大写,冒号替换为双下划线):

bash
APP__NAME=MyApp
APP__VERSION=1.0.0
DATABASE__HOST=localhost
DATABASE__PORT=5432

导出到文件

异步导出到文件

csharp
// 导出到文件
await cfg.ExportSnapshotToFileAsync("config-snapshot.json");

// 使用自定义选项
await cfg.ExportSnapshotToFileAsync("config-snapshot.json", new ExportOptions
{
    Indented = true,
    MaskSensitiveValues = true
});

导出到流

csharp
using var stream = new MemoryStream();
await cfg.ExportSnapshotAsync(stream, new ExportOptions
{
    MaskSensitiveValues = false
});

过滤配置

包含指定键

csharp
// 仅导出 App 和 Database:Host
var filtered = cfg.ExportSnapshot(new ExportOptions
{
    IncludeKeys = new[] { "App:*", "Database:Host" }
});

排除指定键

csharp
// 排除敏感配置
var safe = cfg.ExportSnapshot(new ExportOptions
{
    ExcludeKeys = new[] { "Secrets:*", "Database:Password", "Api:Key" }
});

通配符支持

  • * 匹配任意字符
  • ? 匹配单个字符
csharp
// 匹配所有以 Database 开头的键
IncludeKeys = new[] { "Database:*" }

// 匹配 App:Name 和 App:Version
IncludeKeys = new[] { "App:Name", "App:Version" }

// 排除所有密码和密钥
ExcludeKeys = new[] { "*:Password", "*:Secret", "*:Key" }

敏感值脱敏

默认情况下,导出会对敏感值进行脱敏处理:

csharp
// 启用脱敏(默认)
var masked = cfg.ExportSnapshot(new ExportOptions
{
    MaskSensitiveValues = true
});
// 输出: Database:Password = sec***123

// 禁用脱敏(仅用于调试)
var unmasked = cfg.ExportSnapshot(new ExportOptions
{
    MaskSensitiveValues = false
});
// 输出: Database:Password = secret123

静态方法

也可以直接使用 ConfigExporter 静态类:

csharp
using Apq.Cfg.Snapshot;

// 导出为字符串
var json = ConfigExporter.Export(cfg);

// 导出为字典
var dict = ConfigExporter.ExportToDictionary(cfg);

// 导出到文件
await ConfigExporter.ExportToFileAsync(cfg, "snapshot.json");

// 导出到流
await ConfigExporter.ExportAsync(cfg, stream);

自定义导出器

使用 SnapshotExporter 委托可以创建自定义导出格式:

csharp
using Apq.Cfg.Snapshot;

// 使用 Lambda 表达式创建自定义导出器
var yaml = cfg.ExportSnapshot((data, ctx) =>
{
    var sb = new StringBuilder();

    if (ctx.IncludeMetadata)
    {
        sb.AppendLine($"# Exported at: {ctx.ExportedAt:O}");
        sb.AppendLine($"# Key count: {ctx.KeyCount}");
        sb.AppendLine();
    }

    foreach (var (key, value) in data.OrderBy(x => x.Key))
    {
        // 简单的 YAML 格式
        sb.AppendLine($"{key}: \"{value}\"");
    }

    return sb.ToString();
});

// 导出到文件
await cfg.ExportSnapshotToFileAsync((data, ctx) =>
{
    // 自定义格式逻辑
    return string.Join("\n", data.Select(x => $"{x.Key}={x.Value}"));
}, "config.txt");

ExportContext 属性

自定义导出器可以使用 ExportContext 获取导出上下文信息:

属性类型说明
ExportedAtDateTime导出时间(UTC)
IncludeMetadatabool是否包含元数据
Indentedbool是否缩进格式化
EnvPrefixstring?环境变量前缀
KeyCountint配置键数量
PropertiesIDictionary<string, object?>自定义属性

内置导出器

导出器说明
SnapshotExporters.Json嵌套 JSON 结构
SnapshotExporters.KeyValue扁平键值对
SnapshotExporters.Env环境变量格式
csharp
// 直接使用内置导出器
var json = cfg.ExportSnapshot(SnapshotExporters.Json);
var kv = cfg.ExportSnapshot(SnapshotExporters.KeyValue);
var env = cfg.ExportSnapshot(SnapshotExporters.Env);

使用场景

调试配置问题

csharp
// 在应用启动时导出配置快照
var snapshot = cfg.ExportSnapshotAsJson(maskSensitive: true);
logger.LogDebug("Configuration snapshot:\n{Snapshot}", snapshot);

配置备份

csharp
// 定期备份配置
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
await cfg.ExportSnapshotToFileAsync($"backup/config_{timestamp}.json", new ExportOptions
{
    Indented = true,
    MaskSensitiveValues = false  // 备份需要完整值
});

配置迁移

csharp
// 导出为环境变量格式,用于容器部署
var envContent = cfg.ExportSnapshotAsEnv(prefix: "APP_");
await File.WriteAllTextAsync(".env.production", envContent);

配置比较

csharp
// 导出两个环境的配置进行比较
var devConfig = devCfg.ExportSnapshotAsDictionary();
var prodConfig = prodCfg.ExportSnapshotAsDictionary();

var differences = devConfig.Keys
    .Where(k => !prodConfig.ContainsKey(k) || devConfig[k] != prodConfig[k])
    .ToList();

API 参考

ExportOptions 属性

属性类型默认值说明
IndentedbooltrueJSON 是否缩进
IncludeMetadataboolfalse是否包含元数据
MaskSensitiveValuesbooltrue是否脱敏敏感值
IncludeKeysstring[]?null仅包含的键(支持通配符)
ExcludeKeysstring[]?null排除的键(支持通配符)
EnvPrefixstring?null环境变量格式的前缀

扩展方法

方法说明
ExportSnapshot()导出为字符串
ExportSnapshot(options)使用选项导出
ExportSnapshot(configure)使用构建器模式导出
ExportSnapshotAsJson()导出为 JSON
ExportSnapshotAsEnv()导出为环境变量格式
ExportSnapshotAsDictionary()导出为字典
ExportSnapshotToFileAsync()导出到文件
ExportSnapshotAsync()导出到流

基于 MIT 许可发布