aspire-configuration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Aspire Configuration

Aspire配置

When to Use This Skill

何时使用此技巧

Use this skill when:
  • Wiring AppHost resources to application configuration in Aspire-based repos
  • Ensuring production configuration is transparent and portable outside of Aspire
  • Avoiding Aspire client/service-discovery packages inside application code
  • Designing feature toggles for dev/test without changing app code paths

使用此技巧的场景:
  • 在基于Aspire的代码库中,将AppHost资源与应用配置关联时
  • 确保生产环境配置在Aspire之外也具备透明性与可移植性时
  • 希望在应用代码中避免引入Aspire客户端/服务发现包时
  • 无需修改应用代码路径,即可为开发/测试环境设计功能开关时

Core Principles

核心原则

  1. AppHost owns Aspire infrastructure packages
    • Aspire Hosting packages belong in AppHost only.
    • App projects should not reference Aspire client/service-discovery packages.
  2. Explicit configuration only
    • AppHost must translate resource outputs into explicit config keys (env vars).
    • App code binds to
      IOptions<T>
      or
      Configuration
      only.
  3. Production parity and transparency
    • Every value injected by AppHost must be representable in production as env vars or config files without Aspire.
    • Avoid opaque service discovery and implicit configuration.

  1. AppHost专属Aspire基础设施包
    • Aspire Hosting包仅应存在于AppHost中。
    • 应用项目不应引用Aspire客户端/服务发现包。
  2. 仅使用显式配置
    • AppHost必须将资源输出转换为明确的配置键(环境变量)。
    • 应用代码仅绑定到
      IOptions<T>
      Configuration
  3. 生产环境一致性与透明性
    • AppHost注入的每一个值,都必须能在生产环境中通过环境变量或配置文件来设置,无需依赖Aspire。
    • 避免使用不透明的服务发现与隐式配置。

Configuration Flow

配置流程

AppHost resource -> WithEnvironment(...) -> app config keys -> IOptions<T> in app
The AppHost is responsible for turning Aspire resources into explicit app settings. The application never consumes Aspire clients or service discovery directly.

AppHost resource -> WithEnvironment(...) -> app config keys -> IOptions<T> in app
AppHost负责将Aspire资源转换为明确的应用设置。应用永远不会直接使用Aspire客户端或服务发现功能。

AppHost Patterns (Explicit Mapping)

AppHost模式(显式映射)

Example: Database + Blob Storage

示例:数据库 + 对象存储

csharp
// AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var db = postgres.AddDatabase("appdb");

var minio = builder.AddContainer("minio", "minio/minio")
    .WithArgs("server", "/data")
    .WithHttpEndpoint(targetPort: 9000, name: "http")
    .WithHttpEndpoint(targetPort: 9001, name: "console")
    .WithEnvironment("MINIO_ROOT_USER", "minioadmin")
    .WithEnvironment("MINIO_ROOT_PASSWORD", "minioadmin");

var api = builder.AddProject<Projects.MyApp_Api>("api")
    .WithReference(db, "Postgres")
    .WithEnvironment("BlobStorage__Enabled", "true")
    .WithEnvironment("BlobStorage__ServiceUrl", minio.GetEndpoint("http"))
    .WithEnvironment("BlobStorage__AccessKey", "minioadmin")
    .WithEnvironment("BlobStorage__SecretKey", "minioadmin")
    .WithEnvironment("BlobStorage__Bucket", "attachments")
    .WithEnvironment("BlobStorage__ForcePathStyle", "true");

builder.Build().Run();
Key points
  • WithReference(db, "Postgres")
    sets
    ConnectionStrings__Postgres
    explicitly.
  • Every external dependency is represented via explicit config keys.
  • The API project only reads
    Configuration
    values.

csharp
// AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var db = postgres.AddDatabase("appdb");

var minio = builder.AddContainer("minio", "minio/minio")
    .WithArgs("server", "/data")
    .WithHttpEndpoint(targetPort: 9000, name: "http")
    .WithHttpEndpoint(targetPort: 9001, name: "console")
    .WithEnvironment("MINIO_ROOT_USER", "minioadmin")
    .WithEnvironment("MINIO_ROOT_PASSWORD", "minioadmin");

var api = builder.AddProject<Projects.MyApp_Api>("api")
    .WithReference(db, "Postgres")
    .WithEnvironment("BlobStorage__Enabled", "true")
    .WithEnvironment("BlobStorage__ServiceUrl", minio.GetEndpoint("http"))
    .WithEnvironment("BlobStorage__AccessKey", "minioadmin")
    .WithEnvironment("BlobStorage__SecretKey", "minioadmin")
    .WithEnvironment("BlobStorage__Bucket", "attachments")
    .WithEnvironment("BlobStorage__ForcePathStyle", "true");

builder.Build().Run();
关键要点
  • WithReference(db, "Postgres")
    会显式设置
    ConnectionStrings__Postgres
  • 每一个外部依赖都通过明确的配置键来表示。
  • API项目仅读取
    Configuration
    中的值。

App Code Pattern (No Aspire Clients)

应用代码模式(无Aspire客户端)

Application code binds to options and initializes SDKs directly. It never depends on Aspire client packages or service discovery.
csharp
// Api/Program.cs
builder.Services
    .AddOptions<BlobStorageOptions>()
    .BindConfiguration("BlobStorage")
    .ValidateDataAnnotations()
    .ValidateOnStart();

builder.Services.AddSingleton<IBlobStorageService>(sp =>
{
    var options = sp.GetRequiredService<IOptions<BlobStorageOptions>>().Value;
    return new S3BlobStorageService(options); // uses explicit options only
});
Do not add Aspire client packages (or
AddServiceDiscovery
) to the app. Those are orchestration concerns and should stay in AppHost.

应用代码绑定到选项并直接初始化SDK,永远不依赖Aspire客户端包或服务发现功能。
csharp
// Api/Program.cs
builder.Services
    .AddOptions<BlobStorageOptions>()
    .BindConfiguration("BlobStorage")
    .ValidateDataAnnotations()
    .ValidateOnStart();

builder.Services.AddSingleton<IBlobStorageService>(sp =>
{
    var options = sp.GetRequiredService<IOptions<BlobStorageOptions>>().Value;
    return new S3BlobStorageService(options); // uses explicit options only
});
请勿在应用项目中添加Aspire客户端包(或
AddServiceDiscovery
)。这些是编排层面的关注点,应仅保留在AppHost中。

Feature Toggles and Test Overrides

功能开关与测试覆盖

Keep toggles in config and drive them through AppHost and test fixtures. This maintains parity between dev/test and production configuration.
csharp
// AppHost: disable persistence in tests via config overrides
var config = builder.Configuration.GetSection("App")
    .Get<AppHostConfiguration>() ?? new AppHostConfiguration();

if (!config.UseVolumes)
{
    postgres.WithDataVolume(false);
}

api.WithEnvironment("BlobStorage__Enabled", config.EnableBlobStorage.ToString());
See
skills/aspire/integration-testing/SKILL.md
for patterns on passing configuration overrides into
DistributedApplicationTestingBuilder
.

将开关保存在配置中,通过AppHost与测试夹具来控制。这样可以保持开发/测试环境与生产环境的配置一致性。
csharp
// AppHost: disable persistence in tests via config overrides
var config = builder.Configuration.GetSection("App")
    .Get<AppHostConfiguration>() ?? new AppHostConfiguration();

if (!config.UseVolumes)
{
    postgres.WithDataVolume(false);
}

api.WithEnvironment("BlobStorage__Enabled", config.EnableBlobStorage.ToString());
有关如何将配置覆盖传递到
DistributedApplicationTestingBuilder
的模式,请参阅
skills/aspire/integration-testing/SKILL.md

Do / Don’t Checklist

注意事项清单

Do
  • Map every Aspire resource output to explicit configuration keys
  • Use
    IOptions<T>
    with validation for all infrastructure settings
  • Keep AppHost as the only place that references Aspire hosting packages
  • Ensure any AppHost-injected value can be set in production env vars
Don’t
  • Reference Aspire client/service-discovery packages in application projects
  • Rely on opaque service discovery that cannot be mirrored in production
  • Hide configuration behind Aspire-only abstractions

建议
  • 将每一个Aspire资源输出映射到明确的配置键
  • 对所有基础设施设置使用带验证的
    IOptions<T>
  • 仅在AppHost中引用Aspire hosting包
  • 确保AppHost注入的任何值都能在生产环境的环境变量中设置
避免
  • 在应用项目中引用Aspire客户端/服务发现包
  • 依赖无法在生产环境中复刻的不透明服务发现
  • 将配置隐藏在仅Aspire支持的抽象层之后

Related Skills

相关技巧

  • skills/aspire/service-defaults/SKILL.md
  • skills/aspire/integration-testing/SKILL.md
  • skills/akka/aspire-configuration/SKILL.md

  • skills/aspire/service-defaults/SKILL.md
  • skills/aspire/integration-testing/SKILL.md
  • skills/akka/aspire-configuration/SKILL.md

Resources

参考资源