mcpField
C
configuration

configuration

github.com/codewithmukesh开发7913.0k 次安装12 周前更新
代码仓库

关于 configuration

面向 .NET 开发的配置实践指南,介绍如何使用强类型选项、验证和分层配置源管理应用设置。也涵盖机密信息处理和命名选项配置。

主要功能

  1. 01强类型选项绑定
  2. 02启动时验证配置
  3. 03分层配置来源
  4. 04机密信息存储建议
  5. 05命名选项

适用场景

  1. 01将设置绑定到经过验证的类
  2. 02在启动时发现配置错误
  3. 03将机密信息与源代码分离

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/codewithmukesh/dotnet-claude-kit --skill configuration

安装后在 Claude Code 中输入/configuration确认已加载。

详细介绍

配置

核心原则

  1. 始终使用 Options 模式 — 切勿在服务中直接读取 IConfiguration。将配置节绑定到强类型类,并进行验证。
  2. 启动时验证 — 使用 ValidateDataAnnotations() 和 ValidateOnStart(),在首次请求前发现配置错误。
  3. 源代码中绝不包含密钥 — 开发时使用用户机密,生产环境使用 Azure Key Vault 或环境变量。切勿将密钥提交到 git。
  4. 配置分层 — appsettings.json → appsettings.{Environment}.json → 环境变量 → 用户机密。后面的来源会覆盖前面的来源。

模式

Options 模式
// Options class with validation attributes
public class DatabaseOptions
{
    public const string SectionName = "Database";

    [Required]
    public required string ConnectionString { get; init; }

    [Range(1, 100)]
    public int MaxRetryCount { get; init; } = 3;

    [Range(1, 60)]
    public int CommandTimeoutSeconds { get; init; } = 30;
}

// Registration with validation
builder.Services.AddOptions<DatabaseOptions>()
    .BindConfiguration(DatabaseOptions.SectionName)
    .ValidateDataAnnotations()
    .ValidateOnStart(); // Fails at startup if configuration is invalid
// appsettings.json
{
  "Database": {
    "ConnectionString": "",
    "MaxRetryCount": 3,
    "CommandTimeoutSeconds": 30
  }
}
注入 Options
// IOptions<T> — singleton, read once at startup, doesn't change
public class OrderService(IOptions<DatabaseOptions> options)
{
    private readonly DatabaseOptions _db = options.Value;
}

// IOptionsSnapshot<T> — scoped, re-reads per request (for reloadable config)
public class OrderService(IOptionsSnapshot<DatabaseOptions> options)
{
    private readonly DatabaseOptions _db = options.Value;
}

// IOptionsMonitor<T> — singleton, actively watches for changes
public class BackgroundWorker(IOptionsMonitor<WorkerOptions> options)
{
    public void DoWork()
    {
        var current = options.CurrentValue; // Always latest
    }
}
自定义验证(复杂规则)
builder.Services.AddOptions<JwtOptions>()
    .BindConfiguration("Jwt")
    .Validate(options =>
    {
        if (string.IsNullOrEmpty(options.Key) || options.Key.Length < 32)
            return false;
        if (options.ExpirationMinutes <= 0)
            return false;
        return true;
    }, "JWT key must be at least 32 characters and expiration must be positive")
    .ValidateOnStart();
Azure Key Vault(生产环境)
// Program.cs — add Key Vault as a configuration source
if (builder.Environment.IsProduction())
{
    var keyVaultUri = new Uri(builder.Configuration["KeyVault:Uri"]!);
    builder.Configuration.AddAzureKeyVault(keyVaultUri, new DefaultAzureCredential());
}
多环境配置
// Named options — different config per named instance
builder.Services.AddOptions<SmtpOptions>("internal")
    .BindConfiguration("Smtp:Internal");
builder.Services.AddOptions<SmtpOptions>("customer")
    .BindConfiguration("Smtp:Customer");

// Usage
public class EmailService(IOptionsSnapshot<SmtpOptions> options)
{
    public async Task SendInternalEmail(string to, string body)
    {
        var smtp = options.Get("internal");
        // ...
    }
}

反模式

不要直接读取 IConfiguration
// BAD — stringly-typed, no validation, hard to test
public class OrderService(IConfiguration config)
{
    public void Process()
    {
        var timeout = int.Parse(config["Database:CommandTimeout"]!);
    }
}

// GOOD — strongly-typed options
public class OrderService(IOptions<DatabaseOptions> options)
{
    public void Process()
    {
        var timeout = options.Value.CommandTimeoutSeconds;
    }
}
不要将密钥放在 appsettings.json 中
// BAD — committed to source control
{
  "Jwt": { "Key": "super-secret-key" },
  "Database": { "ConnectionString": "Server=prod;Password=secret" }
}

// GOOD — appsettings.json has defaults/structure only
{
  "Jwt": { "Key": "", "Issuer": "myapp", "Audience": "myapp" },
  "Database": { "ConnectionString": "" }
}
// Secrets provided via user-secrets (dev) or env vars / Key Vault (prod)
不要跳过启动验证
// BAD — misconfiguration discovered at runtime
builder.Services.Configure<JwtOptions>(builder.Configuration.GetSection("Jwt"));

// GOOD — fail fast at startup
builder.Services.AddOptions<JwtOptions>()
    .BindConfiguration("Jwt")
    .ValidateDataAnnotations()
    .ValidateOnStart();

决策指南

场景建议
将配置绑定到类使用 BindConfiguration 的 Options 模式
简单、不可变的配置IOptions<T>
每个请求都会变化的配置IOptionsSnapshot<T>
监视配置的后台服务IOptionsMonitor<T>
开发环境密钥dotnet user-secrets
生产环境密钥Azure Key Vault 或环境变量
验证配置ValidateDataAnnotations() + ValidateOnStart()
同一类型的多个配置使用 IOptionsSnapshot<T>.Get(name) 的命名 Options

评论

支持 Markdown