A .NET 10 orchestration API that fans out to multiple public weather APIs in parallel and returns a consolidated response.
WeatherAggregator/
├── Directory.Build.props ← net10.0, Nullable, ImplicitUsings for ALL projects
├── Directory.Packages.props ← Central Package Management — all NuGet versions here
├── src/
│ ├── WeatherAggregator.Domain ← Zero dependencies — enums, interfaces, exceptions
│ ├── WeatherAggregator.Application ← Wolverine handler, FluentValidation, extension methods
│ ├── WeatherAggregator.Infrastructure← Castle interceptor, typed HttpClients, Autofac module
│ └── WeatherAggregator.API ← Program.cs, minimal API endpoint, middleware
└── tests/
├── WeatherAggregator.Tests.Unit ← NSubstitute, FluentAssertions, Bogus
└── WeatherAggregator.Tests.Integration ← WebApplicationFactory + WireMock.Net
Pattern
Where
Clean Architecture
4 layer project structure
CQRS (Wolverine)
AggregateWeatherCommand + Handler
AOP Interceptor
AuditInterceptor on all 4 HttpClients
Fan-out + Consolidate
Task.WhenAll in handler
Cache-aside
GeocodingClient + IMemoryCache
Options pattern
ServiceClientOptions per service
Anti-Corruption Layer
ExternalDtos → Domain models
Problem Details RFC 7807
GlobalExceptionHandler
Open WeatherAggregator.sln in Visual Studio 2022/2026
Set WeatherAggregator.API as startup project
Press F5
Open weather.http and send requests using VS HTTP client
POST /api/v1/weather/aggregate ← Main orchestration endpoint
GET /healthz/live ← Kubernetes liveness probe
GET /healthz/ready ← Kubernetes readiness probe (pings external APIs)
GET /openapi/v1.json ← OpenAPI spec (development only)
POST /api/v1/weather/aggregate
{
"currentWeather" : { "location" : " Sydney" , "temperatureUnit" : " celsius" },
"airQuality" : { "location" : " Sydney" },
"astronomy" : { "location" : " Sydney" },
"forecast" : { "location" : " Sydney" , "days" : 3 }
}
{
"aggregationId" : " AGG-20250510-A3F2" ,
"status" : " Completed" ,
"requestedAt" : " 2025-05-10T10:00:00Z" ,
"completedAt" : " 2025-05-10T10:00:00.8Z" ,
"results" : [
{
"service" : " CurrentWeather" ,
"status" : " Success" ,
"durationMs" : 187 ,
"data" : { "temperature" : 22.4 , "feelsLike" : 21.0 , "humidity" : 65 , ... },
"errorMessage" : null
}
]
}
External APIs Used (all free, no API key)
Service
URL
Current Weather
api.open-meteo.com
Air Quality
air-quality-api.open-meteo.com
Geocoding
geocoding-api.open-meteo.com
Astronomy
api.sunrise-sunset.org
Forecast
api.open-meteo.com
No Serilog — uses Microsoft.Extensions.Logging with console provider only.
Castle AuditInterceptor logs every outbound HTTP call (request + response + duration).
WolverineFx.FluentValidation runs validators automatically before handlers — no pipeline behaviors needed.
Central Package Management — all NuGet versions in Directory.Packages.props, never in individual .csproj files.