C# Academy · 课时

配置源与提供程序

按优先级从 JSON 文件、环境变量、命令行参数和自定义提供程序分层加载配置。

第 1 / 4 课13 个步骤

配置源与提供程序 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。

.NET 中的配置

ASP.NET Core 的配置系统会从多个来源读取设置——JSON 文件、环境变量、命令行参数等——并将它们合并到一个扁平的键值存储中,您可以在应用的任何位置访问该存储。

appsettings.json

appsettings.json 是默认的配置文件。它会由 Host.CreateApplicationBuilder 自动加载。设置会与特定环境的覆盖设置合并。

// appsettings.json
{
  "App": {
    "Name": "OrderService",
    "MaxRetries": 3
  },
  "ConnectionStrings": {
    "Default": "Server=localhost;Database=orders"
  }
}

// appsettings.Production.json overrides the above:
{
  "ConnectionStrings": {
    "Default": "Server=prod-db;Database=orders;..."
  }
}

读取配置值

通过 IConfiguration 访问配置。嵌套对象的键使用冒号表示法。数组通过索引访问。

// Inject IConfiguration
public class OrderService
{
    private readonly IConfiguration _config;

    public OrderService(IConfiguration cfg) => _config = cfg;

    public void Configure()
    {
        string? name     = _config["App:Name"];           // "OrderService"
        int maxRetries   = _config.GetValue<int>("App:MaxRetries"); // 3
        string? connStr  = _config.GetConnectionString("Default");

        // Nested section
        var section = _config.GetSection("App");
        string? appName = section["Name"];
    }
}

环境变量

环境变量会覆盖 JSON 设置,对于容器化部署至关重要。在嵌套键中,双下划线(__)会替代冒号分隔符。

# Set via shell or docker-compose:
export App__Name="OrderService-Prod"
export App__MaxRetries=5
export ConnectionStrings__Default="Server=prod-db;..."

// Equivalent to:
{
  "App": { "Name": "OrderService-Prod", "MaxRetries": 5 },
  "ConnectionStrings": { "Default": "Server=prod-db;..." }
}

// Priority: env vars > appsettings.{Environment}.json > appsettings.json

命令行参数

默认情况下,命令行参数具有最高优先级。它们使用 --key=value 或 --key value 语法,并使用冒号或双下划线表示嵌套关系。

# Override config when launching the app:
dotnet run --App:Name="CLI-Override" --App:MaxRetries=10

# Or:
dotnet run --App__Name="CLI-Override"

// The builder.Configuration.AddCommandLine() is called
// automatically by Host.CreateApplicationBuilder().

// Priority order (highest to lowest):
// 1. Command-line args
// 2. Environment variables
// 3. appsettings.{ASPNETCORE_ENVIRONMENT}.json
// 4. appsettings.json

用户机密

用户机密会在开发期间将敏感配置存储在项目目录之外。它们绝不会提交到源代码管理中,并且会在本地覆盖 appsettings.json。

# Initialize user secrets for the project:
dotnet user-secrets init

# Set a secret:
dotnet user-secrets set "Database:Password" "SuperSecret123"
dotnet user-secrets set "Jwt:SecretKey" "dev-only-key"

# List secrets:
dotnet user-secrets list

# Remove:
dotnet user-secrets remove "Database:Password"

# Stored in: ~/.microsoft/usersecrets/{projectId}/secrets.json
# Automatically loaded in Development environment only

自定义配置提供程序

实现 IConfigurationProvider 和 IConfigurationSource,即可从任意来源加载配置,例如数据库、Consul、Vault、Redis 等。

public class DbConfigProvider : ConfigurationProvider
{
    private readonly string _connStr;
    public DbConfigProvider(string connStr) => _connStr = connStr;

    public override void Load()
    {
        using var conn = new NpgsqlConnection(_connStr);
        conn.Open();
        using var cmd = new NpgsqlCommand(
            "SELECT key, value FROM app_config", conn);
        using var reader = cmd.ExecuteReader();
        while (reader.Read())
            Data[reader.GetString(0)] = reader.GetString(1);
    }
}

public class DbConfigSource : IConfigurationSource
{
    private readonly string _connStr;
    public DbConfigSource(string connStr) => _connStr = connStr;
    public IConfigurationProvider Build(IConfigurationBuilder b)
        => new DbConfigProvider(_connStr);
}

注册自定义提供程序

在调用 Build() 之前,将自定义配置源添加到 builder 中。它会加入与内置提供程序相同的优先级链。

var builder = Host.CreateApplicationBuilder(args);

// Add custom DB config provider after appsettings.json
builder.Configuration.Add(
    new DbConfigSource(
        builder.Configuration.GetConnectionString("Default")!));

// Or as an extension method:
public static class ConfigExtensions
{
    public static IConfigurationBuilder AddDatabaseConfig(
        this IConfigurationBuilder b, string connStr)
        => b.Add(new DbConfigSource(connStr));
}

// Usage:
builder.Configuration.AddDatabaseConfig(connStr);

Azure App Configuration

Azure App Configuration 通过功能开关、标签和版本控制,集中管理各个微服务的设置。官方提供程序会将其集成为标准配置源。

// dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
// dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore

builder.Configuration.AddAzureAppConfiguration(options =>
    options
        .Connect(builder.Configuration["AzureAppConfig:ConnectionString"])
        .Select(KeyFilter.Any)                 // all keys
        .Select(KeyFilter.Any, "Production")   // label override
        .UseFeatureFlags(ff =>
            ff.CacheExpirationInterval = TimeSpan.FromMinutes(5))
        .ConfigureRefresh(r =>
            r.Register("App:Version", refreshAll: true)
             .SetCacheExpiration(TimeSpan.FromMinutes(1)))
);

app.UseAzureAppConfiguration(); // enable dynamic refresh

重新加载配置

某些提供程序支持更改检测。JSON 提供程序可以在文件发生更改时重新加载。请使用 IOptionsMonitor<T> 在运行时响应更改。

// Enable JSON file reload on change:
builder.Configuration.AddJsonFile("appsettings.json",
    optional: false, reloadOnChange: true);

// In a service, use IOptionsMonitor (not IOptions) to get live values:
public class FeatureService
{
    private readonly IOptionsMonitor<FeatureFlags> _monitor;

    public FeatureService(IOptionsMonitor<FeatureFlags> m) => _monitor = m;

    public bool IsBetaEnabled
        => _monitor.CurrentValue.BetaEnabled; // always fresh

    // React to changes:
    public FeatureService(IOptionsMonitor<FeatureFlags> m)
    {
        _monitor = m;
        m.OnChange(flags => Console.WriteLine("Config changed!"));
    }
}

快速检查

要将嵌套的 JSON 配置键表示为环境变量,应使用什么分隔符?

实战:多源配置

一个结合 appsettings、环境变量和用户机密,并明确规定优先级顺序的生产环境配置方案。

var builder = Host.CreateApplicationBuilder(args);

// Default: appsettings.json → appsettings.{env}.json → env vars → CLI
// Add user secrets in development:
if (builder.Environment.IsDevelopment())
    builder.Configuration.AddUserSecrets<Program>();

// Optionally add Azure Key Vault in production:
if (!builder.Environment.IsDevelopment())
{
    var keyVaultUri = builder.Configuration["Azure:KeyVaultUri"]!;
    builder.Configuration.AddAzureKeyVault(
        new Uri(keyVaultUri), new DefaultAzureCredential());
}

// Now all secrets are available transparently via IConfiguration
var jwtKey = builder.Configuration["Jwt:SecretKey"]!;

回顾:配置源与提供程序

要点:

  • 配置会从多个来源合并;后加载的来源会覆盖先加载的来源
  • 优先级:CLI 参数 > 环境变量 > appsettings.{env}.json > appsettings.json
  • 在环境变量中使用 __(双下划线)表示嵌套键
  • 用户机密可以避免将开发凭据置于源代码管理中
  • 自定义提供程序:实现 IConfigurationSource + IConfigurationProvider
  • 使用 reloadOnChange: true + IOptionsMonitor 实现实时配置更新
免费开始

用 AI 导师学习 C# — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
93
课程
346

常见问题解答

「配置源与提供程序」课时是免费的吗?

是的 — 「配置源与提供程序」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。

「配置源与提供程序」这节课中我会学到什么?

按优先级从 JSON 文件、环境变量、命令行参数和自定义提供程序分层加载配置。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C# Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「配置源与提供程序」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C# Academy 课中编写并运行代码吗?

能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 配置源与提供程序
  2. 使用 IOptions 的强类型选项
  3. 选项验证与命名选项
  4. 机密管理
← 返回 C# Academy