Skip to footer content
Iron Academy Logo
C# Tools & Productivity

Intro To Aspire 9.5 - Get Started Quickly with This Essential Tool

Tim Corey
43m 49s

Every modern .NET developer working with web applications should know how to use Aspire 9.5. In his detailed video, “Intro to Aspire 9.5 – Get Started Quickly with This Essential Tool,” Tim Corey introduces this new .NET Aspire system, explaining what it is, why it’s valuable, and how to get started quickly.

Throughout the video, Tim builds an example solution step-by-step, using Visual Studio and the latest project templates. This article follows his walkthrough closely, providing a complete guide to the project files, setup process, and the developer experience Aspire brings to building production-ready distributed apps.

Getting Started and Installing Aspire 9.5

Tim begins by explaining the purpose of Aspire. Every .NET developer who builds APIs or web applications should understand this essential Microsoft tool. There’s been confusion about what Aspire can do, so Tim sets out to demonstrate its purpose, setup, and usage from the ground up.

He opens Visual Studio and starts a new project using the Aspire starter app template. If you don’t have Aspire installed, he points to Microsoft’s website for setup and tooling for Aspire, noting that you can install it through the .NET CLI, Visual Studio, or VS Code. For simplicity, Tim recommends using the CLI command:

dotnet new install aspire.templates

This installs the latest project templates, including Aspire 9.5. After installation, Visual Studio may require a restart for the templates to appear.

Tim selects the Aspire Demo App, chooses .NET 9, enables HTTPS, and uses Redis integration for caching. This demonstrates a real-world scenario where Aspire manages an entire app locally. He skips unit testing and proceeds with creating the solution files.

Exploring the Project Structure and App Model

Once the project is generated, Tim breaks down the project files created by Aspire’s app model. The solution includes four main projects that reflect both typical .NET projects and Aspire-specific ones:

  1. Web project – a Blazor-based web application.

  2. API service – a backend service for data or business logic.

  3. AppHost – the single file AppHost that launches the entire app.

  4. ServiceDefaults – a library containing health checks, service discovery, and telemetry setup.

The first two represent a normal distributed system (frontend and backend), while the other two represent Aspire’s unified toolchain for managing environment variables, dependencies, and resource lifecycle event APIs.

Tim highlights how this new app model provides first-class support for multi-project orchestration, letting developers run their entire app with one command. The AppHost controls startup order and dependencies, while ServiceDefaults injects configuration defaults, health checks, and telemetry integration automatically.

Why Aspire Simplifies Local Development

Tim explains the pain points of managing a distributed system locally without Aspire. Traditionally, developers must configure container runtime setups, port forwarding, and connection strings for each service manually. Each developer must replicate environment variables, user secrets, and redis or API connections individually.

With Aspire, the Aspire CLI handles this automatically. It spins up dependencies such as Redis containers through a dev container or Docker instance, manages endpoint discovery, and provides private access between services using service discovery.

Aspire uses a reverse proxy and endpoint resolution system so the web frontend doesn’t need to know hardcoded port numbers. It simply refers to the API by name (like "apiservice")—Aspire figures out the rest.

This drastically improves the developer experience by removing tedious setup steps, letting developers focus on code, not infrastructure.

Defining Services and Dependencies in AppHost

Tim shows the heart of Aspire’s configuration: the AppHost’s Program.cs file. Using a var builder pattern, Aspire defines each service with simple commands such as:

var cache = builder.AddRedis("cache");
var api = builder.AddProject<Projects.ApiService>("apiservice");
var web = builder.AddProject<Projects.Web>("webfrontend")
    .WithReference(cache)
    .WithReference(api);
var cache = builder.AddRedis("cache");
var api = builder.AddProject<Projects.ApiService>("apiservice");
var web = builder.AddProject<Projects.Web>("webfrontend")
    .WithReference(cache)
    .WithReference(api);

This syntax defines each resource, sets up dependency order, and creates a clear resource lifecycle. Aspire automatically handles waiting for dependencies, ensuring the cache starts first, then the API, then the web frontend.

This small set of instructions gives developers granular control over startup behavior, mirroring how things would run in production-ready distributed apps.

Running Aspire and Understanding the Dashboard

When Tim runs the project, Aspire launches its own container runtime and opens the Aspire Dashboard—a central interface to monitor everything. Initially, an error appears: “Container runtime unhealthy”—Docker wasn’t running. Once Docker starts, Aspire automatically initializes a Redis executable resource and connects it to the rest of the app.

The dashboard displays color-coded status icons, indicating the health of each resource. Once Redis, the API, and the web frontend are all running, the dashboard turns green, showing that the entire app is healthy.

This notification system instantly reflects real-time states, providing clearer error messages than standard console logs. Developers can visualize service relationships, monitor metrics, and even access resource endpoints directly from the UI.

Visual Insights Through the Aspire Dashboard

The graph view in the dashboard visualizes how services connect. For example, the web frontend connects to both Redis and the API service, while the API is independent. This trace view helps understand the internal flow of calls and dependencies.

Tim highlights that the dashboard includes trace detail improvements, such as displaying trace filtering options and timing breakdowns. Developers can trace HTTP requests across services and see performance impacts using Aspire’s traces view.

Centralized Logging and Structured Logs

Aspire unifies console logs from all project files into one view. Instead of juggling multiple log windows, developers can use the dashboard to view logs from all services—web app, API, and Redis integration—in one timeline.

Tim shows that Aspire uses structured logging, allowing context-rich entries such as IDs, parameters, and tags. Developers can filter logs by level (Info, Warning, Error) or property values.

For example, a developer can view only entries where "evenOddResult" == "odd". This advanced log filtering, combined with Aspire’s color-coded prefixes, makes debugging intuitive and visual.

Working with Traces and Telemetry

In the Traces tab, Tim demonstrates how Aspire tracks requests across the app’s services. Each trace contains timing, status, and spans showing which service processed what.

For example, a “GetWeather” request shows when the cache was hit or missed, when the API call occurred, and how long each action took. This trace filtering allows precise identification of bottlenecks and dependencies.

Aspire also supports OpenTelemetry for exporting trace data to other tools or systems, giving developers full observability across distributed services.

Real-Time Metrics and Performance Monitoring

Tim explores metrics like request durations, SignalR active connections, and active request counts. These metrics visualize the live state of your app and provide early detection of connection or latency issues.

Metrics data in Aspire 9.5 also benefits from trace detail improvements and better trace filtering, letting developers pinpoint where performance dips occur in real time.

Aspire Is for Local Development, Not Production

Tim clearly notes that Aspire’s dashboard isn’t meant for deployment to production servers. Deploying it would expose internal system details and environment variables, which could be risky.

However, developers can still use Aspire’s aspire deploy command to publish services to Azure Container Apps, Azure Container App Jobs, or other Aspire integrations. These deployment options are growing but remain separate from the dashboard.

Aspire’s purpose is to mirror a production-like environment locally with safe upgrades and preview support, not to replace production monitoring systems.

Experimenting with Logging and Exception Handling

Tim adds structured logging in the Counter page and deliberately introduces a NotImplementedException in the Weather page. When rerunning, the dashboard immediately captures both structured logs and unhandled exceptions.

He shows how Aspire’s logs display full details, including the parameter name, values, and the call stack. The integration with GitHub Models and Copilot AI allows automatic explanations of exceptions and code suggestions for fixes—an example of early AI services and generative AI visualizer integration into the developer experience.

Analyzing Errors with Trace Filtering

In the Traces tab, Tim demonstrates how failed API calls appear with red exclamation icons. Clicking one reveals all related logs filtered by span ID, linking each request across multiple .NET projects.

This unified view—logs, traces, and health checks combined—provides interactive prompting for debugging and building observable systems without external configuration.

Integrating Aspire into Existing .NET Projects

Tim then explains how to integrate Aspire into an existing app. Developers only need to add two things:

  • The AppHost project, which controls what services start and their dependencies.

  • The ServiceDefaults project, which provides feature flags, health checks, telemetry, and service discovery.

By referencing ServiceDefaults in each project file, developers automatically get default environment variables, logging setup, and telemetry. Aspire’s endpoint resolution system removes the need for manual port forwarding or connection string management.

Expanding Aspire Beyond Local Use

Tim addresses how Aspire’s capabilities are expanding beyond local use. With Azure Container Apps and Azure AI Foundry integrations, developers can use the Aspire CLI to deploy distributed systems with minimal configuration.

The system already supports custom resource icons, name properties, and preview support for ai services like OpenAI endpoints or Azure PostgreSQL connections.

Aspire’s unified toolchain also supports version control and safe upgrades between major versions and minor versions, helping teams adopt updates like Aspire 9.5 confidently.

Final Thoughts and Future Outlook

As the video concludes, Tim calls Aspire “a goldmine for developers.” The dashboard combines traces view, health checks, logs, and metrics into a single unified panel—something previously unavailable in local development.

For Tim and his team, every new .NET Aspire project now uses this system by default. It makes custom builds faster, improves the developer experience, and ensures production-ready distributed apps behave consistently across machines.

He notes that major Aspire releases will continue to refine trace filtering, endpoint resolution, and ai integrations, while maintaining a focus on safe upgrades and general availability.

Tim encourages everyone to explore Aspire 9.5, use it in their next .NET projects, and leverage its one command simplicity to view logs, manage dev tunnels, and test the entire app locally with confidence.

Hero Worlddot related to Intro To Aspire 9.5 - Get Started Quickly with This Essential Tool
Hero Affiliate related to Intro To Aspire 9.5 - Get Started Quickly with This Essential Tool

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!