.NET Aspire Distributed Applications
Simplify orchestration of distributed .NET applications.
By EMEPublished: February 20, 2025
dotnet aspireorchestrationdistributed systemsmicroservices
A Simple Analogy
.NET Aspire is like a conductor's score for your services. Define all services in one place, how they connect, and Aspire orchestrates them during development and guides production deployment.
What Is .NET Aspire?
.NET Aspire is a stack for building cloud-native distributed applications with built-in orchestration, observability, and configuration management.
Project Structure
MyDistributedApp/
├── MyDistributedApp.AppHost/ # Orchestration
├── MyDistributedApp.ServiceDefaults/ # Shared defaults
├── Api.Service/ # API service
├── Worker.Service/ # Background service
└── Db.Migrations/ # Database migrations
Orchestration (AppHost)
// Program.cs
var builder = DistributedApplication.CreateBuilder(args);
// Add services
var apiServicePort = 5001;
var apiService = builder
.AddProject<Projects.ApiService>("apiservice")
.WithHttpEndpoint(port: apiServicePort, targetPort: 80);
var workerService = builder
.AddProject<Projects.WorkerService>("workerservice");
// Add database
var postgres = builder
.AddPostgres("postgres")
.AddDatabase("appdb");
// Add message broker
var rabbitmq = builder
.AddRabbitMQ("rabbitmq")
.WithManagementPlugin();
// Connect services to resources
apiService
.WithReference(postgres)
.WithReference(rabbitmq);
workerService
.WithReference(postgres)
.WithReference(rabbitmq);
// Add dashboard
builder.AddProject<Projects.WebApi>("webapi")
.WithReference(apiService);
var app = builder.Build();
await app.RunAsync();
Service Implementation
// ApiService/Program.cs
var builder = WebApplication.CreateBuilder(args);
// Use Aspire service defaults
builder.AddServiceDefaults();
// Add services
builder.Services.AddScoped<IOrderService, OrderService>();
var app = builder.Build();
// Use Aspire defaults (middleware)
app.UseServiceDefaults();
app.MapPost("/api/orders", async (CreateOrderRequest req, IOrderService service) =>
{
return await service.CreateAsync(req);
});
app.Run();
// ServiceDefaults/Extensions.cs
public static class Extensions
{
public static IServiceCollection AddServiceDefaults(this IServiceCollection services)
{
// Add health checks
services.AddHealthChecks()
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
// Add observability
services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation());
return services;
}
public static WebApplication UseServiceDefaults(this WebApplication app)
{
app.MapHealthChecks("/health");
app.UseOpenTelemetryPrometheusScrap();
return app;
}
}
Database Integration
// AppHost
var postgres = builder
.AddPostgres("postgres", password: "password")
.AddDatabase("appdb");
// In service
builder.Services.AddDbContext<AppDbContext>((sp, options) =>
{
var connection = sp.GetRequiredService<IConfiguration>().GetConnectionString("appdb");
options.UseNpgsql(connection);
});
Configuration Management
// AppHost
var apiKey = builder.AddParameter("ApiKey");
var apiService = builder
.AddProject<Projects.ApiService>("apiservice")
.WithEnvironment("API_KEY", apiKey);
// In service
var apiKey = app.Configuration["API_KEY"];
Practical Example
# Full distributed app
Projects:
- ApiService
- WorkerService
- Dashboard
Resources:
- PostgreSQL database
- RabbitMQ message broker
- Redis cache
- Open Telemetry collector
Networking:
All services can reference each other by name
Environment variables injected automatically
Observability:
Logs aggregated
Traces collected
Metrics exposed
Best Practices
- Use AppHost for orchestration: Central place for topology
- Implement health checks: Enable liveness/readiness
- Use service defaults: Shared configuration
- Add observability: Traces, logs, metrics
- Document dependencies: Clarify service relationships
Related Concepts
- Docker Compose (simpler)
- Kubernetes (production)
- Service mesh for advanced networking
- GitOps for declarative deployment
Summary
.NET Aspire streamlines building and orchestrating cloud-native distributed applications. Define your entire application topology in code with automatic service discovery and observability.