1 Getting Started with Aspire in .NET
Aspire burst onto the scene alongside .NET 8, quickly gaining traction by addressing a long-standing pain point: developing and debugging distributed applications locally with minimal friction. Its promise is to run an entire multi-service system in a unified, developer-friendly workflow, aligning local and production behaviors much like Docker did for environments. The product evolved into an evergreen release (version 13), decoupled from .NET’s cadence and rebranded from “.NET Aspire” to simply “Aspire,” with optional support for non-.NET workloads such as JavaScript and Python—while this chapter keeps the focus on building with .NET.
The chapter first grounds readers in distributed systems fundamentals—contrasting microservices with modular monoliths—and outlines key benefits (scalability, agility, technology diversity, resilience) and trade-offs (operational complexity, testing challenges, performance overhead, security). It then introduces orchestration concepts like deployment, scaling, health monitoring, configuration, and resource management. Against this backdrop, Aspire is positioned as a cloud-native application stack that streamlines building, running, and monitoring multi-service applications via a declarative application model, integrated infrastructure components (databases, brokers), built-in observability with OpenTelemetry (traces, logs, metrics), and cloud-readiness for smooth moves from local development to production—ultimately boosting developer productivity.
Practically, the chapter walks through a starter solution composed of a Blazor UI, an API service, and an AppHost orchestrator, all visible and controllable via an Aspire dashboard that exposes service states, endpoints, and logs. It explains how the host uses a specialized builder to register projects, health checks, and dependencies, and how services can be secured and sequenced with features like external endpoint exposure, readiness ordering, and references for inter-service communication. A ServiceDefaults library centralizes cross-cutting setup—telemetry, health checks, service discovery, and resilient HTTP clients—while service discovery enables name-based addressing (for example, targeting a service by its registered name rather than a fixed URL) with smart protocol preferences. Together, these pieces form a coherent foundation for orchestrating, observing, and evolving distributed applications in Aspire.
Example of a distributed application
Modular monolith structure
Orchestrated system
Hosting code and infrastructure components in the same Aspire process
The structure of the Aspire solution
Aspire dashboard
Aspire console log
Aspire Resources webfrontend link
Blazor app hosted in Aspire
Summary
- Aspire was created by Microsoft to make the process of developing distributed applications easy.
- Distributed applications are systems that consist of multiple independent services that interact with each other.
- Orchestration is the process of coordinating services inside a distributed system
- The main benefit of using Aspire is that it allows running and debugging a distributed application in a single process on a development machine, which substantially simplifies the development process
- Aspire consists of the Aspire Host project, which all other projects can connect to
- Different applications hosted by Aspire can pass each other’s references to each other when they are registered by the orchestrator
- The Service Defaults project is used for shared dependencies that any Aspire-hosted apps can use
- Service discovery allows for resolving addresses of Aspire-hosted apps via the names the apps were registered under in the orchestrator
- Aspire orchestrator displays a dashboard, which shows the status of all running services
FAQ
What is Aspire, and why did it gain so much attention in the .NET community?
Aspire (formerly .NET Aspire) is an orchestrator and cloud-native application stack that makes it easy to build, run, and debug distributed applications locally. Released unexpectedly alongside .NET 8/C# 12, it streamlined local development of multi-service apps by running services together, wiring dependencies, and enabling shared debugging—leading to rapid community and enterprise adoption.How does Aspire simplify local development and debugging of distributed applications?
Aspire lets you launch an entire distributed app (multiple services plus infrastructure like databases/message brokers) from a single host process, discover services automatically, and debug them together. This brings development/production parity similar to Docker and removes the need to manually start many processes or mock services.What is the Aspire Host project, and how do I start my app?
The Host (e.g., OnlineShop.AppHost) is the orchestrator. You run it to build, start, and coordinate all services. Its startup usesDistributedApplication.CreateBuilder(args) and registers each service via AddProject<T>(), adding health checks and relationships. Starting the Host opens the Aspire dashboard with service status, endpoints, and logs.What does the Aspire dashboard show, and how do I use it?
The dashboard lists each service’s type, unique Aspire name, state/health, source project, endpoints, logs, and details. You can open endpoints directly, review console logs, and check health. Running with HTTP vs HTTPS affects how many endpoints you see (one vs two per service in local dev).How do I register services in the Host, and what do WaitFor, WithReference, and WithExternalHttpEndpoints do?
-AddProject<T>("name") registers a project as a service (type T is auto-generated from the project).-
WithHttpHealthCheck("/health") exposes a health endpoint for orchestration/monitoring.-
WithExternalHttpEndpoints() makes endpoints reachable from outside Aspire’s internal network (e.g., public internet).-
WaitFor(service) delays startup until the dependency is ready.-
WithReference(service) wires a dependency for service discovery and configuration.What are “Service Defaults,” and why are they a separate class library?
Service Defaults (e.g., OnlineShop.ServiceDefaults) are shared extension methods that each app calls to integrate with Aspire. They enable service discovery, health checks, telemetry/metrics, and common HTTP client behavior. Keeping them in a library lets teams customize choices (e.g., telemetry exporters) to fit business needs.How is observability built into Aspire?
Aspire integrates with OpenTelemetry for logging, tracing, and metrics. In Service Defaults,ConfigureOpenTelemetry() adds ASP.NET Core, HTTP client, and runtime instrumentation; AddOpenTelemetryExporters() enables exporting via OTEL_EXPORTER_OTLP_ENDPOINT. Health endpoints (e.g., /health and /alive) are mapped via MapDefaultEndpoints() for readiness/liveness checks.How does service discovery work in Aspire, and how do services call each other?
InstallMicrosoft.Extensions.ServiceDiscovery and enable it in Service Defaults with builder.Services.AddServiceDiscovery() and http.AddServiceDiscovery(). Clients then use a logical service name instead of a fixed URL, e.g., client.BaseAddress = new("https+http://apiservice"). Aspire resolves the actual address, prefers HTTPS, and falls back to HTTP if needed.
.NET Aspire Made Easy ebook for free