Adds .NET Aspire cloud-native orchestration to existing .NET solutions...
This skill helps add .NET Aspire to existing .NET solutions or create new Aspire-enabled distributed applications. It provides modular guidance for orchestration, service discovery, component integration, configuration management, and deployment.
.NET Aspire is an opinionated, cloud-ready stack for building observable, production-ready, distributed applications. It provides:
Use this skill when:
| Need | Resource | Description |
|---|---|---|
| Overall structure | Overview & Setup | Step-by-step implementation from analysis to running |
| Database, cache, messaging | resources/components.md |
All available Aspire component packages with examples |
| Inter-service communication | resources/service-communication.md |
Service discovery, HttpClient patterns, resilience |
| Configuration & secrets | resources/configuration-management.md |
Environment settings, secrets, feature flags |
| Local development | resources/local-development.md |
Dashboard, debugging, testing, health checks |
| Production deployment | resources/deployment.md |
Azure Container Apps, Kubernetes, Docker Compose |
.NET Aspire uses two key projects:
# Install .NET Aspire workload
dotnet workload install aspire
# Verify installation
dotnet workload list # Should show "aspire"
# Docker Desktop (for container resources)
# Ensure it's running before launching AppHost
1. Analyze the solution
2. Create Aspire projects
dotnet new aspire-apphost -n MyApp.AppHost
dotnet new aspire-servicedefaults -n MyApp.ServiceDefaults
dotnet sln add MyApp.AppHost/MyApp.AppHost.csproj
dotnet sln add MyApp.ServiceDefaults/MyApp.ServiceDefaults.csproj
3. Configure services
builder.AddServiceDefaults() in Program.csapp.MapDefaultEndpoints() for ASP.NET Core services4. Orchestrate in AppHost
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var database = builder.AddPostgres("postgres").AddDatabase("appdb");
var api = builder.AddProject<Projects.MyApi>("api")
.WithReference(database)
.WithReference(cache);
var web = builder.AddProject<Projects.MyWeb>("web")
.WithReference(api)
.WithExternalHttpEndpoints();
builder.Build().Run();
5. Update service communication
builder.AddServiceDefaults() pattern matching6. Run and verify
dotnet run --project MyApp.AppHost
# Opens dashboard at https://localhost:15001
AppHost Project Naming:
[SolutionName].AppHostService Resource Names:
Resource Management:
azd or manually configuredService Discovery Setup:
http://api instead of https://localhost:7001var api = builder.AddProject<Projects.Api>("api")
.WithReference(database)
.WithExternalHttpEndpoints();
var web = builder.AddProject<Projects.Web>("web")
.WithReference(api)
.WithExternalHttpEndpoints();
var messaging = builder.AddRabbitMQ("messaging");
var orderService = builder.AddProject<Projects.OrderService>("orders")
.WithReference(messaging);
var inventoryService = builder.AddProject<Projects.InventoryService>("inventory")
.WithReference(messaging);
var postgres = builder.AddPostgres("postgres")
.AddDatabase("users")
.AddDatabase("products");
var mongo = builder.AddMongoDB("mongo")
.AddDatabase("orders");
var userApi = builder.AddProject<Projects.UserApi>("userapi")
.WithReference(postgres);
var orderApi = builder.AddProject<Projects.OrderApi>("orderapi")
.WithReference(mongo);
For detailed implementation guidance, see:
resources/components.mdresources/service-communication.mdresources/configuration-management.mdresources/local-development.mdresources/deployment.md.WithReference().WithDataVolume()appsettings.Development.json and .WithEnvironment()Services can't communicate
AddServiceDefaults() is called in all servicesMapDefaultEndpoints()Connection strings not injected
builder.AddNpgsqlDbContext<>() instead of manual configurationDashboard won't start
Health checks failing
AddServiceDefaults() and MapDefaultEndpoints()dotnet run --project AppHostresources/components.mdresources/service-communication.mdresources/configuration-management.mdresources/local-development.mdresources/deployment.mdRemember: Start with a single service, verify communication works, then add complexity. Use the dashboard to debug issues locally before deploying to production.
Before implementing, confirm with the user:
Service Identification:
Infrastructure Requirements:
Aspire Structure:
Dependencies:
Create the AppHost project:
dotnet new aspire-apphost -n [SolutionName].AppHost
The AppHost project:
Program.cs with application compositionCreate the ServiceDefaults project:
dotnet new aspire-servicedefaults -n [SolutionName].ServiceDefaults
The ServiceDefaults project:
Add projects to solution:
dotnet sln add [SolutionName].AppHost/[SolutionName].AppHost.csproj
dotnet sln add [SolutionName].ServiceDefaults/[SolutionName].ServiceDefaults.csproj
For each service project (API, Web App, Worker):
dotnet add [ServiceProject] reference [SolutionName].ServiceDefaults/[SolutionName].ServiceDefaults.csproj
// At the top of Program.cs, after builder creation
var builder = WebApplication.CreateBuilder(args);
// Add this line
builder.AddServiceDefaults();
// ... rest of service configuration ...
var app = builder.Build();
// Add this line before app.Run()
app.MapDefaultEndpoints();
app.Run();
var builder = Host.CreateApplicationBuilder(args);
builder.AddServiceDefaults();
// ... service configuration ...
var host = builder.Build();
host.Run();
Add project references in AppHost:
dotnet add [SolutionName].AppHost reference [ServiceProject1]/[ServiceProject1].csproj
dotnet add [SolutionName].AppHost reference [ServiceProject2]/[ServiceProject2].csproj
Update AppHost Program.cs to orchestrate services:
var builder = DistributedApplication.CreateBuilder(args);
// Add infrastructure resources
var cache = builder.AddRedis("cache");
var postgres = builder.AddPostgres("postgres")
.AddDatabase("appdb");
// Add services with dependencies
var apiService = builder.AddProject<Projects.MyApi>("apiservice")
.WithReference(postgres)
.WithReference(cache);
var webApp = builder.AddProject<Projects.MyWebApp>("webapp")
.WithReference(apiService)
.WithExternalHttpEndpoints();
builder.Build().Run();
Common resource methods:
.AddRedis("name") - Redis cache.AddPostgres("name").AddDatabase("dbname") - PostgreSQL.AddSqlServer("name").AddDatabase("dbname") - SQL Server.AddRabbitMQ("name") - RabbitMQ messaging.AddMongoDB("name").AddDatabase("dbname") - MongoDB.AddAzureStorage("name") - Azure StorageService configuration methods:
.WithReference(resource) - Add dependency and inject connection info.WithExternalHttpEndpoints() - Make service accessible externally.WithReplicas(count) - Run multiple instances.WithEnvironment("KEY", "value") - Add environment variables.WithHttpsEndpoint(port: 7001) - Specify HTTPS portAspire packages are automatically added by templates, but verify:
AppHost project:
Aspire.Hosting.AppHost (typically included via workload)Aspire.Hosting.PostgreSQL)ServiceDefaults project:
Microsoft.Extensions.Http.ResilienceMicrosoft.Extensions.ServiceDiscoveryOpenTelemetry.Exporter.OpenTelemetryProtocolOpenTelemetry.Extensions.HostingOpenTelemetry.Instrumentation.AspNetCoreOpenTelemetry.Instrumentation.HttpOpenTelemetry.Instrumentation.RuntimeService projects:
Aspire.Npgsql.EntityFrameworkCore.PostgreSQL (if using PostgreSQL)Aspire.StackExchange.Redis (if using Redis)Install packages:
dotnet add [Project] package [PackageName]
For services that call other services, use service discovery:
Before (hardcoded URLs):
builder.Services.AddHttpClient("apiservice", client =>
{
client.BaseAddress = new Uri("https://localhost:7001");
});
After (service discovery):
builder.Services.AddHttpClient("apiservice", client =>
{
client.BaseAddress = new Uri("http://apiservice");
});
The service name matches the name in AppHost's AddProject<>() call.
For typed HttpClients:
builder.Services.AddHttpClient<IApiClient, ApiClient>(client =>
{
client.BaseAddress = new Uri("http://apiservice");
});
Resource connection strings are automatically injected. Update service configuration:
Before:
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
After:
builder.AddNpgsqlDbContext<AppDbContext>("appdb");
The connection name ("appdb") matches the database name in AppHost.
For Redis:
builder.AddRedisClient("cache");
Run the AppHost project:
dotnet run --project [SolutionName].AppHost
This launches:
Verify:
For services not in the solution:
var externalApi = builder.AddProject<Projects.ExternalApi>("external-api")
.WithHttpsEndpoint(port: 8001);
Run services in containers:
var myApi = builder.AddContainer("myapi", "myapiimage")
.WithHttpEndpoint(port: 8000, targetPort: 80);
For Azure-hosted resources:
var storage = builder.AddAzureStorage("storage")
.AddBlobs("blobs");
var keyVault = builder.AddAzureKeyVault("keyvault");
Extend Aspire with custom resources:
var customResource = builder.AddResource(new CustomResource("name"))
.WithEndpoint("http", endpoint => endpoint.Port = 9000);
appsettings.Development.json for local overrides.WithReference() to inject connection informationvar apiGateway = builder.AddProject<Projects.ApiGateway>("gateway")
.WithExternalHttpEndpoints();
var serviceA = builder.AddProject<Projects.ServiceA>("servicea");
var serviceB = builder.AddProject<Projects.ServiceB>("serviceb");
apiGateway.WithReference(serviceA).WithReference(serviceB);
var messaging = builder.AddRabbitMQ("messaging");
var worker = builder.AddProject<Projects.Worker>("worker")
.WithReference(messaging);
var api = builder.AddProject<Projects.Api>("api")
.WithReference(messaging);
var cache = builder.AddRedis("cache");
var database = builder.AddPostgres("postgres").AddDatabase("appdb");
var api = builder.AddProject<Projects.Api>("api")
.WithReference(database)
.WithReference(cache);
var web = builder.AddProject<Projects.Web>("web")
.WithReference(api)
.WithExternalHttpEndpoints();
builder.AddServiceDefaults() is called in service Program.csapp.MapDefaultEndpoints() is called for ASP.NET servicesbuilder.AddNpgsqlDbContext<>() instead of manual AddDbContextWhen adding Aspire to an existing solution, expect to modify:
Ensure the following are installed:
dotnet workload install aspireVerify installation:
dotnet workload list
Should show "aspire" in the installed workloads.
After implementing Aspire, verify:
AddServiceDefaults() and MapDefaultEndpoints()For detailed information about specific components and patterns, see:
resources/components.md - Aspire component packages and configurationsresources/deployment.md - Deploying Aspire applications to productionWhen complete, the solution structure should look like:
MySolution/
├── MySolution.sln
├── MySolution.AppHost/
│ ├── Program.cs # Orchestration configuration
│ ├── MySolution.AppHost.csproj
│ └── appsettings.json
├── MySolution.ServiceDefaults/
│ ├── Extensions.cs # Service defaults implementation
│ └── MySolution.ServiceDefaults.csproj
├── MySolution.Api/
│ ├── Program.cs # Calls AddServiceDefaults()
│ └── MySolution.Api.csproj # References ServiceDefaults
├── MySolution.Web/
│ ├── Program.cs # Calls AddServiceDefaults()
│ └── MySolution.Web.csproj # References ServiceDefaults
└── MySolution.Worker/
├── Program.cs # Calls AddServiceDefaults()
└── MySolution.Worker.csproj # References ServiceDefaults
Running dotnet run --project MySolution.AppHost starts all services and opens the dashboard for monitoring and debugging the distributed application.