$npx -y skills add wshaddix/dotnet-skills --skill dotnet-aspire-patternsUsing .NET Aspire. AppHost orchestration, service discovery, components, dashboard, health checks.
| 1 | # dotnet-aspire-patterns |
| 2 | |
| 3 | .NET Aspire orchestration patterns for building cloud-ready distributed applications. Covers AppHost configuration, service discovery, the component model for integrating backing services (databases, caches, message brokers), the Aspire dashboard for local observability, distributed health checks, and when to choose Aspire vs manual container orchestration. |
| 4 | |
| 5 | **Out of scope:** Raw Dockerfile authoring and multi-stage builds -- see [skill:dotnet-containers]. Kubernetes manifests, Helm charts, and Docker Compose -- see [skill:dotnet-container-deployment]. OpenTelemetry SDK configuration and custom metrics -- see [skill:dotnet-observability]. DI service lifetime mechanics -- see [skill:dotnet-csharp-dependency-injection]. Background service hosting -- see [skill:dotnet-background-services]. |
| 6 | |
| 7 | Cross-references: [skill:dotnet-containers] for container image optimization and base image selection, [skill:dotnet-container-deployment] for production Kubernetes/Compose deployment, [skill:dotnet-observability] for OpenTelemetry details beyond Aspire defaults, [skill:dotnet-csharp-dependency-injection] for DI fundamentals, [skill:dotnet-background-services] for hosted service lifecycle patterns. |
| 8 | |
| 9 | --- |
| 10 | |
| 11 | ## Aspire Overview |
| 12 | |
| 13 | .NET Aspire is an opinionated stack for building observable, production-ready distributed applications. It provides: |
| 14 | |
| 15 | - **Orchestration** -- define your distributed topology in C# (the AppHost) |
| 16 | - **Components** -- pre-configured NuGet packages for common backing services |
| 17 | - **Service Defaults** -- shared configuration for OpenTelemetry, health checks, resilience |
| 18 | - **Dashboard** -- local development UI for traces, logs, metrics, and resource status |
| 19 | |
| 20 | Aspire is not a deployment target. It orchestrates the local development and testing experience. For production, it generates manifests consumed by deployment tools (Azure Developer CLI, Kubernetes, etc.). |
| 21 | |
| 22 | ### When to Use Aspire |
| 23 | |
| 24 | | Scenario | Recommendation | |
| 25 | |----------|---------------| |
| 26 | | Multiple .NET services + backing infrastructure | Aspire AppHost -- simplifies local dev and service wiring | |
| 27 | | Single API with a database | Optional -- Aspire adds overhead for simple topologies | |
| 28 | | Non-.NET services only (Node, Python) | Aspire can reference container images, but the tooling benefit is reduced | |
| 29 | | Need Kubernetes/Compose for local dev already | Evaluate migration cost; Aspire replaces docker-compose for dev scenarios | |
| 30 | | Team needs consistent observability defaults | Aspire ServiceDefaults standardize OTel across all projects | |
| 31 | |
| 32 | --- |
| 33 | |
| 34 | ## AppHost Configuration |
| 35 | |
| 36 | The AppHost is a .NET project (`Aspire.Hosting.AppHost` SDK) that defines the distributed application topology. It references other projects and backing services, wiring them together with service discovery. |
| 37 | |
| 38 | ### AppHost Project Setup |
| 39 | |
| 40 | ```xml |
| 41 | <Project Sdk="Microsoft.NET.Sdk"> |
| 42 | |
| 43 | <!-- Aspire SDK version is independent of .NET TFM; 9.x works on net8.0+ --> |
| 44 | <Sdk Name="Aspire.AppHost.Sdk" Version="9.1.*" /> |
| 45 | |
| 46 | <PropertyGroup> |
| 47 | <OutputType>Exe</OutputType> |
| 48 | <TargetFramework>net10.0</TargetFramework> |
| 49 | <IsAspireHost>true</IsAspireHost> |
| 50 | </PropertyGroup> |
| 51 | |
| 52 | <ItemGroup> |
| 53 | <PackageReference Include="Aspire.Hosting.AppHost" Version="9.1.*" /> |
| 54 | <PackageReference Include="Aspire.Hosting.PostgreSQL" Version="9.1.*" /> |
| 55 | <PackageReference Include="Aspire.Hosting.Redis" Version="9.1.*" /> |
| 56 | <PackageReference Include="Aspire.Hosting.RabbitMQ" Version="9.1.*" /> |
| 57 | </ItemGroup> |
| 58 | |
| 59 | <ItemGroup> |
| 60 | <ProjectReference Include="..\MyApi\MyApi.csproj" /> |
| 61 | <ProjectReference Include="..\MyWorker\MyWorker.csproj" /> |
| 62 | </ItemGroup> |
| 63 | |
| 64 | </Project> |
| 65 | ``` |
| 66 | |
| 67 | ### Defining the Topology |
| 68 | |
| 69 | ```csharp |
| 70 | var builder = DistributedApplication.CreateBuilder(args); |
| 71 | |
| 72 | // Backing services -- Aspire manages containers automatically |
| 73 | var postgres = builder.AddPostgres("pg") |
| 74 | .WithPgAdmin() // Adds pgAdmin UI container |
| 75 | .AddDatabase("ordersdb"); |
| 76 | |
| 77 | var redis = builder.AddRedis("cache") |
| 78 | .WithRedisCommander(); // Adds Redis Commander UI |
| 79 | |
| 80 | var rabbitmq = builder.AddRabbitMQ("messaging") |
| 81 | .WithManagementPlugin(); // Adds RabbitMQ management UI |
| 82 | |
| 83 | // Application projects -- wired with service discovery |
| 84 | var api = builder.AddProject<Projects.MyApi>("api") |
| 85 | .WithReference(postgres) |
| 86 | .WithReference(redis) |
| 87 | .WithReference(rabbitmq) |
| 88 | .WithExternalHttpEndpoints(); // Marks endpoints as public in deployment manifests |
| 89 | |
| 90 | builder.AddProject<Projects.MyWorker>("worker") |
| 91 | .WithReference(postgres) |
| 92 | .WithReference(rabbitmq) |
| 93 | .WaitFor(api); // Start worker after API is healthy |
| 94 | |
| 95 | builder.Build().Run(); |
| 96 | ``` |
| 97 | |
| 98 | ### Resource Lifecycle |
| 99 | |
| 100 | `WaitFor` controls startup ordering. Resources wait until dependencies report healthy before starting: |
| 101 | |
| 102 | ```csharp |
| 103 | // Worker waits for both the database and API to be ready |
| 104 | builder.AddProject<Proj |