|
| 1 | +# Aspire AppHost Orchestration — Minimal Sample |
| 2 | + |
| 3 | +A minimal .NET 10 Aspire sample demonstrating how one AppHost starts two .NET |
| 4 | +projects, connects them with a logical reference, and enables the web project |
| 5 | +to call the API through service discovery without a fixed localhost port. |
| 6 | + |
| 7 | +## Full tutorial |
| 8 | + |
| 9 | +[Aspire in .NET: Orchestrate, Run, and Deploy a Distributed System from One App Host](https://www.dotnet-guide.com/tutorials/dotnet-aspire/orchestrate-distributed-system/) |
| 10 | + |
| 11 | +## What this sample demonstrates |
| 12 | + |
| 13 | +* one Aspire AppHost; |
| 14 | +* one API project; |
| 15 | +* one web project; |
| 16 | +* service discovery through `https+http://api`; |
| 17 | +* project references and `WithReference(api)`; |
| 18 | +* startup ordering with `WaitFor(api)`; |
| 19 | +* an externally reachable web endpoint through `WithExternalHttpEndpoints`; |
| 20 | +* dashboard visibility of both resources; |
| 21 | +* web-to-API communication resolved by the AppHost. |
| 22 | + |
| 23 | +## Architecture |
| 24 | + |
| 25 | +```text |
| 26 | +AppHost |
| 27 | +├── api ── GET /message |
| 28 | +└── web ── GET / (calls api through service discovery) |
| 29 | + │ |
| 30 | + └── WithReference(api) |
| 31 | + └── WaitFor(api) |
| 32 | +``` |
| 33 | + |
| 34 | +## File structure |
| 35 | + |
| 36 | +```text |
| 37 | +orchestrate-distributed-system/ |
| 38 | +├── AspireOrchestrationMinimal.slnx |
| 39 | +├── README.md |
| 40 | +├── AspireOrchestrationMinimal.AppHost/ |
| 41 | +│ ├── AppHost.cs |
| 42 | +│ └── AspireOrchestrationMinimal.AppHost.csproj |
| 43 | +├── AspireOrchestrationMinimal.Api/ |
| 44 | +│ ├── Program.cs |
| 45 | +│ └── AspireOrchestrationMinimal.Api.csproj |
| 46 | +└── AspireOrchestrationMinimal.Web/ |
| 47 | + ├── Program.cs |
| 48 | + └── AspireOrchestrationMinimal.Web.csproj |
| 49 | +``` |
| 50 | + |
| 51 | +## Prerequisites |
| 52 | + |
| 53 | +* .NET 10 SDK |
| 54 | +* HTTPS development certificate trusted (run `dotnet dev-certs https --trust`) |
| 55 | + |
| 56 | +No Docker, Podman, PostgreSQL, Redis, API keys, or cloud credentials are required. |
| 57 | + |
| 58 | +## Run the sample |
| 59 | + |
| 60 | +Open a terminal in this sample folder and run: |
| 61 | + |
| 62 | +```powershell |
| 63 | +dotnet restore |
| 64 | +dotnet build --configuration Release |
| 65 | +dotnet run --project AspireOrchestrationMinimal.AppHost |
| 66 | +``` |
| 67 | + |
| 68 | +The AppHost starts both projects. The Aspire dashboard opens automatically. |
| 69 | + |
| 70 | +## Verify the sample |
| 71 | + |
| 72 | +### Dashboard |
| 73 | + |
| 74 | +Confirm that the Aspire dashboard shows: |
| 75 | + |
| 76 | +* `api` — started successfully |
| 77 | +* `web` — started successfully, waited for `api` |
| 78 | +* both endpoints are visible |
| 79 | + |
| 80 | +### Web endpoint |
| 81 | + |
| 82 | +Open the web endpoint shown in the dashboard. The page displays: |
| 83 | + |
| 84 | +```text |
| 85 | +Aspire orchestration sample |
| 86 | +
|
| 87 | +Web resource: running |
| 88 | +API response: {"message":"Hello from the Aspire-managed API","service":"api"} |
| 89 | +``` |
| 90 | + |
| 91 | +### API endpoint |
| 92 | + |
| 93 | +```text |
| 94 | +GET / → AspireOrchestrationMinimal.Api is running. |
| 95 | +GET /message → {"message":"Hello from the Aspire-managed API","service":"api"} |
| 96 | +``` |
| 97 | + |
| 98 | +## Service discovery |
| 99 | + |
| 100 | +The web project uses: |
| 101 | + |
| 102 | +```csharp |
| 103 | +client.BaseAddress = new Uri("https+http://api"); |
| 104 | +``` |
| 105 | + |
| 106 | +The resource name `api` matches the AppHost declaration: |
| 107 | + |
| 108 | +```csharp |
| 109 | +var api = builder.AddProject<Projects.AspireOrchestrationMinimal_Api>("api"); |
| 110 | +``` |
| 111 | + |
| 112 | +Aspire resolves the logical name at runtime. The web project contains **no** |
| 113 | +fixed localhost port such as `http://localhost:5001`. |
| 114 | + |
| 115 | +## `WithReference` versus `WaitFor` |
| 116 | + |
| 117 | +| Method | Purpose | |
| 118 | +| --- | --- | |
| 119 | +| `WithReference(api)` | Supplies service-discovery and configuration information to the referencing project | |
| 120 | +| `WaitFor(api)` | Controls startup ordering — the web project does not start until the API is ready | |
| 121 | + |
| 122 | +They solve different problems. This sample uses both. |
| 123 | + |
| 124 | +## Important boundary |
| 125 | + |
| 126 | +This repository sample intentionally does **not** reproduce the complete tutorial. |
| 127 | + |
| 128 | +The full DOTNET GUIDE tutorial additionally contains: |
| 129 | + |
| 130 | +* PostgreSQL and Redis integration |
| 131 | +* ServiceDefaults project |
| 132 | +* EF Core and Npgsql |
| 133 | +* database migrations |
| 134 | +* caching |
| 135 | +* custom health-check and readiness packages |
| 136 | +* `Aspire.Hosting.Testing` |
| 137 | +* integration-test projects |
| 138 | +* OpenTelemetry customization |
| 139 | +* generative-AI telemetry |
| 140 | +* publishing (`aspire publish`) |
| 141 | +* deployment (`aspire deploy`) |
| 142 | +* Azure deployment guidance |
| 143 | +* Kubernetes and Helm |
| 144 | +* Docker-oriented publishing |
| 145 | +* production secrets, ingress, scaling, and networking |
| 146 | +* complete release-management and production-hardening guidance |
| 147 | + |
| 148 | +## Verification |
| 149 | + |
| 150 | +| Item | Detail | |
| 151 | +| --- | --- | |
| 152 | +| Target framework | .NET 10 (`net10.0`) | |
| 153 | +| SDK | .NET SDK 10.0.302 | |
| 154 | +| Aspire version | `Aspire.Hosting.AppHost` 13.4.6 | |
| 155 | +| Service discovery | `Microsoft.Extensions.ServiceDiscovery` 10.8.0 | |
| 156 | +| External services required | None | |
| 157 | +| Containers required | None | |
| 158 | +| API keys required | None | |
| 159 | +| Local restore | Verified | |
| 160 | +| Release build | Verified | |
| 161 | +| Last reviewed | 2026-07-26 | |
| 162 | + |
| 163 | +## License |
| 164 | + |
| 165 | +Repository-owned sample code is available under the [MIT License](../../LICENSE). |
| 166 | + |
| 167 | +Third-party Aspire and .NET packages remain subject to their own licenses. |
0 commit comments