.github/skills/aspire-configuration/SKILL.md
Configure Aspire AppHost to emit explicit app config via environment variables; keep app code free of Aspire clients and service discovery.
npx skillsauth add tientt010/dotnet-jiralite-microservices aspire-configurationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when:
AppHost owns Aspire infrastructure packages
Explicit configuration only
IOptions<T> or Configuration only.Production parity and transparency
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/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.Configuration values.Application code binds to options and initializes SDKs directly. It never depends on Aspire client packages or service discovery.
// 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.
Keep toggles in config and drive them through AppHost and test fixtures. This maintains parity between dev/test and production configuration.
// 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.
Do
IOptions<T> with validation for all infrastructure settingsDon’t
skills/aspire/service-defaults/SKILL.mdskills/aspire/integration-testing/SKILL.mdskills/akka/aspire-configuration/SKILL.mddevelopment
Snapshot test email templates using Verify to catch regressions. Validates rendered HTML output matches approved baseline. Works with MJML templates and any email renderer.
testing
Write integration tests using TestContainers for .NET with xUnit. Covers infrastructure testing with real databases, message queues, and caches in Docker containers instead of mocks.
development
Use Verify for snapshot testing in .NET. Approve API surfaces, HTTP responses, rendered emails, and serialized outputs. Detect unintended changes through human-reviewed baseline files.
development
Use Slopwatch to detect LLM reward hacking in .NET code changes. Run after every code modification to catch disabled tests, suppressed warnings, empty catch blocks, and other shortcuts that mask real problems.