Sometimes I hear, “.NET Aspire is interesting for DevOps, but not so for developers.”, “It’s hard to integrate this with our existing environment”.
Whether you’re a developer looking to streamline your local development setup or a DevOps engineer aiming to optimize deployment pipelines, .NET Aspire offers tools and integrations that cater to both worlds. From pulling necessary services with Docker to enabling structured logging, distributed tracing, and metrics collection, .NET Aspire empowers teams to build robust, scalable, and maintainable applications with minimal effort.
Let me answer this here – What do you get out of .NET Aspire without the deployment aspect. This article explores what needs to be done to add .NET Aspire functionality to existing applications without the built-in Visual Studio feature – adding it step by step which shows the same application can be deployed to an existing environment.

Infrastructure for development
When setting up a development machine, we often need SQL Server, other databases, and caching solutions like Redis. It takes time to install the infrastructure for the developer system, and developers need to learn about all the parts involved. Just having the requirement of Docker (using Docker Desktop or Podman), .NET Aspire pulls all the services needed, and they are automatically connected with visible relationships.
Many Azure resources nowadays offer emulators running within Docker – e.g., Azure Cosmos DB or Azure Event Hub. Not all are available yet, but .NET Aspire makes it easy to create resources within Azure, which can happen just while debugging the application!
Defining an app-model with .NET Aspire makes this easy – everything is here as required to have the application with all the services required as needed.
Using .NET Aspire integrations, they already know about the folders that need to be mapped to keep the state persistent with a Docker volume, prepare a database by using EF Core migrations, or passing SQL scripts to initialize.
Resource usage easily visible while developing
While developing, using .NET Aspire, you can easily monitor the consumption of the solution, check memory usage, monitor how often services are invoked, and compare timings between accessing the database or using a cache.
When I hear about “we already have tests running with CI/CD which return information about issues with memory usage” – this is really great! Many companies don’t have this in place yet. However, when you see this information immediately at the time while working on the feature, you can react immediately instead of learning about issues a day later.
.NET Aspire is great to learn about the behavior of the solution during development, to monitor it and understanding issues.
Deploying the application with .NET Aspire
.NET Aspire also helps with deploying. Deploy to Microsoft Azure? Use Kubernetes? Running the application with a simple Docker Compose?
Many companies are using Internet Information Server (IIS) to run your Web services and Web applications. The App Host project does not create a binary that’s deployed. This project is only used while developing, and to create artifacts for deployment.
It’s not required to use .NET Aspire for deployment. You can still deploy the Web applications and services as you are used to, they are still normal .NET applications (and yes, you can integrate non-.NET applications as well).
Using the new Aspire CLI (currently in preview), it’s becoming even easier to deploy using .NET Aspire. Publishers can be configured with the app model, which allows creating publishing artifacts for Microsoft Azure, Kubernetes, and Docker Compose. Other publishers will follow.
You don’t need to use every feature from .NET Aspire!
While .NET Aspire offers several areas of improvement, it’s not necessary to use all of them. You can enhance your solutions incrementally. What are the actual the pain points you have creating your solution? What could be improved? This should be where to put the focus to.
Using existing solutions, what are the steps that can be done to integrate .NET Aspire?
Let’s get into first steps to add .NET Aspire to an existing project.
Update a project to use .NET Aspire
While it’s easy to add .NET Aspire to an existing project with Visual Studio (select the project in the solution explorer, and select Add | .NET Aspire Orchestrator support, here we’ll do a more manual approach so you can easily see what can be done to get what features.
Create a “traditional” API project
First I’m creating a Web API without any .NET Aspire integration:
mkdir AspireSample
cd AspireSample
dotnet new webapi -o WeatherAPI -f net9.0
Running this project we can see weather information using a link defined with the launchsettings.json, adding weatherforecast, e.g. https://localhost:8765/weatherforecast
Next, let’s add the .NET Aspire AppHost
Create the .NET Aspire AppHost
To create this, I’m using the (currently in preview) .NET Aspire CLI. This tool can be installed with:
dotnet tool install aspire.cli -g --prerelease
Entering aspire new shows available templates:

Select aspire-apphost, and enter these options:
- Project name: Weather.AppHost
- Output path: ./Weather.AppHost
- Select the .NET Aspire version (currently 9.2.1)
Next create a solution file, add the two projects, and add a reference to the AppHost project to reference the API project:
dotnet new solution -n Weather -f slnx
dotnet solution Weather.slnx add Weather.AppHost/Weather.AppHost.csproj
dotnet solution Weather.slnx add WeatherAPI/WeatherAPI.csproj
dotnet reference add WeatherAPI/WeatherAPI.csproj --project Weather.AppHost/Weather.AppHost.csproj
The API project is referenced by the AppHost to allow adding this project in a strongly-typed way to the app model
Weather.AppHost/Program.cs
var builder = DistributedApplication.CreateBuilder(args);
var weatherapi = builder.AddProject("weatherapi");
builder.Build().Run();
The AppHost project has the Aspire.AppHost.Sdk referenced, which adds the IsAppHost setting. With this extension for project references, a metadata is generated. The Projects namespace includes classes the reference the project file.
Weather.AppHost/Weather.AppHost.csproj
<Sdk Name="Aspire.AppHost.Sdk" Version="9.2.1" />
Instead of adding a reference to the API project, it’s also possible to use the non-generic AddProject method, and pass the file-path.
var weatherApi = builder.AddProject("weatherapi", "../WeatherAPI/WeatherAPI.csproj");
With just this information in place, starting the AppHost project starts the dashboard, and the API project.

Checking the Console logs with the dashboard, the logs are shown:
![]()
Without a single change to the API project itself, startup can be customized by e.g. starting multiple replicas, and passing environment variables:
Weather.AppHost/Program.cs
var weatherapi = builder.AddProject("weatherapi")
.WithReplicas(3)
.WithEnvironment("MyEnv1", "some value");
Running the AppHost with this change, three instances of the API project are created, and the environment variable is set with these processes.
The dashboard views for structured logging, traces, and metrics don’t show any values yet – because the API project doesn’t forward this information to the dashboard yet. Let’s change this next.
Adding a Library for Service Defaults
Next some small changes are done to the API project. The functionality is added by using
Enter aspire new again, but select the aspire-servicedefaults template:
- Project name: Weather.ServiceDefaults
- Output path: ./Weather.ServiceDefaults
This library contains extension methods to enhance logging, distributed tracing, and metrics.
This library needs to be referenced from the API project:
dotnet solution Weather.slnx add Weather.ServiceDefaults/Weather.ServiceDefaults.csproj
dotnet reference add Weather.ServiceDefaults/Weather.ServiceDefaults.csproj --project WeatherAPI/WeatherAPI.csproj
Just small code changes are needed with the API to take advantage of this:
WeatherAPI/Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
After creating the WebApplicationBuilder, invoke the AddServiceDefaults method defined by the new library. This configures the DI container.
With the middleware configuration, the extension method MapDefaultEndpoints from the ServiceDefaults library can be invoked:
WeatherAPI/Program.cs
app.MapDefaultEndpoints();
app.Run();
The MapDefaultEndpoints method just specifies health checks which are by default only used in development mode. For production mode you should change the configuration with the library.
With this configuration in place, the dashboard now shows structured logging, distributed tracing, and metrics data.



While developing the application, having this information gives the advantage of finding issues early!
Just small changes are needed with the projects to use OpenTelemetry, and these changes usually don’t restrict already existing deployment options.
After the initial setup, the next steps are using service discovery, and adding database and service resources with .NET Aspire integrations. Then we’ll have the next advantages of .NET Aspire!
Service discovery can easily be configured with .NET Aspire by referencing APIs from applications which transparently forwards the links by using providers with your environments, no matter if Azure or Kubernetes is used. This works with IIS as well as service discovery includes a fallback to a configuration provider.
With .NET Aspire integrations, it’s easy to use different services such as many relational and NoSQL databases, REDIS, Keycloak and more!
For all this and more information about .NET Aspire, read my book Pragmatic Microservices with C# and Azure!
Summary
.NET Aspire simplifies development and deployment by providing a unified framework for managing infrastructure, monitoring resource usage, and integrating services. It allows developers to focus on building features while handling complex tasks like service discovery, distributed tracing, and metrics collection. With minimal changes to existing projects, developers can leverage powerful tools like structured logging and OpenTelemetry support.
Whether you’re deploying to Azure, Kubernetes, or using Docker Compose, .NET Aspire offers flexibility without locking you into specific deployment methods. Its incremental adoption approach ensures you can address pain points without overhauling your existing solutions.
Start small, enhance your projects step by step, and take advantage of .NET Aspire’s integrations with databases, caching solutions, and more. For a deeper dive, explore the resources linked in this article, including the book Pragmatic Microservices with C# and Azure.
Do you already use .NET Aspire? Share your experiences and thoughts in the comments!
For more information:






Leave a comment