aspire-configuration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAspire 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
核心原则
-
AppHost owns Aspire infrastructure packages
- Aspire Hosting packages belong in AppHost only.
- App projects should not reference Aspire client/service-discovery packages.
-
Explicit configuration only
- AppHost must translate resource outputs into explicit config keys (env vars).
- App code binds to or
IOptions<T>only.Configuration
-
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.
-
AppHost专属Aspire基础设施包
- Aspire Hosting包仅应存在于AppHost中。
- 应用项目不应引用Aspire客户端/服务发现包。
-
仅使用显式配置
- AppHost必须将资源输出转换为明确的配置键(环境变量)。
- 应用代码仅绑定到或
IOptions<T>。Configuration
-
生产环境一致性与透明性
- AppHost注入的每一个值,都必须能在生产环境中通过环境变量或配置文件来设置,无需依赖Aspire。
- 避免使用不透明的服务发现与隐式配置。
Configuration Flow
配置流程
AppHost resource -> WithEnvironment(...) -> app config keys -> IOptions<T> in appThe 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 appAppHost负责将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
- sets
WithReference(db, "Postgres")explicitly.ConnectionStrings__Postgres - Every external dependency is represented via explicit config keys.
- The API project only reads values.
Configuration
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 ) to the app.
Those are orchestration concerns and should stay in AppHost.
AddServiceDiscovery应用代码绑定到选项并直接初始化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客户端包(或)。这些是编排层面的关注点,应仅保留在AppHost中。
AddServiceDiscoveryFeature 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 for patterns on passing
configuration overrides into .
skills/aspire/integration-testing/SKILL.mdDistributedApplicationTestingBuilder将开关保存在配置中,通过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());有关如何将配置覆盖传递到的模式,请参阅。
DistributedApplicationTestingBuilderskills/aspire/integration-testing/SKILL.mdDo / Don’t Checklist
注意事项清单
Do
- Map every Aspire resource output to explicit configuration keys
- Use with validation for all infrastructure settings
IOptions<T> - 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.mdskills/aspire/integration-testing/SKILL.mdskills/akka/aspire-configuration/SKILL.md
skills/aspire/service-defaults/SKILL.mdskills/aspire/integration-testing/SKILL.mdskills/akka/aspire-configuration/SKILL.md
Resources
参考资源
- Aspire AppHost environment configuration: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/app-host
- Configuration in .NET: https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration