Tutorial: Add .NET Aspire to an existing .NET app

If you have existing microservices and .NET web app, you can add .NET Aspire to it and get all the included features and benefits. In this article, you add .NET Aspire orchestration to a simple, preexisting .NET 9 project. You learn how to:

  • Understand the structure of the existing microservices app.
  • Enroll existing projects in .NET Aspire orchestration.
  • Understand the changes enrollment makes in the projects.
  • Start the .NET Aspire project.

Prerequisites

To work with .NET Aspire, you need the following installed locally:

For more information, see .NET Aspire setup and tooling, and .NET Aspire SDK.

Get started

Let's start by obtaining the code for the solution:

  1. Open a command prompt and change directories to where you want to store the code.

  2. To clone to .NET 9 example solution, use the following git clone command:

    git clone https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative-devops.git eShopLite
    

Explore the sample app

This article uses a .NET 9 solution with three projects:

  • Data Entities: This project is an example class library. It defines the Product class used in the Web App and Web API.
  • Products: This example Web API returns a list of products in the catalog and their properties.
  • Store: This example Blazor Web App displays the product catalog to website visitors.

Open and start debugging the project to examine its default behavior:

  1. Start Visual Studio and then select File > Open > Project/Solution.

  2. Navigate to the top level folder of the solution you cloned, select eShopLite.sln, and then select Open.

  3. In the Solution Explorer, right-click the eShopLite solution, and then select Configure Startup Projects.

  4. Select Multiple startup projects.

  5. In the Action column, select Start for both the Products and Store projects.

  6. Select OK.

  7. To start debugging the solution, press F5 or select Start.

  8. Two pages open in the browser:

    • A page displays products in JSON format from a call to the Products Web API.
    • A page displays the homepage of the website. In the menu on the left, select Products to see the catalog obtained from the Web API.
  9. To stop debugging, close the browser.

  1. Start Visual Studio Code and open the folder that you cloned. From the terminal where you cloned the repo, run the following command:

    code .
    
  2. Select the Run and Debug menu item, or press Ctrl+Shift+D.

  3. Select the create a launch.json file link.

    Visual Studio Code: Run and Debug create launch.json file.

  4. Copy and paste the following JSON into this file and Save:

    {
        "version": "0.2.0",
        "compounds": [
            {
                "name": "Run all",
                "configurations": [
                    "Run products",
                    "Run store",
                ]
            }
        ],
        "configurations": [
            {
                "name": "Run products",
                "type": "dotnet",
                "request": "launch",
                "projectPath": "${workspaceFolder}/Products/Products.csproj"
            },
            {
                "name": "Run store",
                "type": "dotnet",
                "request": "launch",
                "projectPath": "${workspaceFolder}/Store/Store.csproj"
            }
        ]
    }
    
  5. To start debugging the solution, press F5 or select Start.

  6. Two pages open in the browser:

    • A page displays products in JSON format from a call to the Products Web API.
    • A page displays the homepage of the website. In the menu on the left, select Products to see the catalog obtained from the Web API.
  7. To stop debugging, close the browser, and then select the Stop button twice (once for each running debug instance).


  1. Open a terminal window and change directories into the newly cloned repository.

  2. To start the Products app, run the following command:

    dotnet run --project ./Products/Products.csproj
    
  3. A browser page opens, displaying the JSON for the products.

  4. In a separate terminal window, again change directories to cloned repository.

  5. Start the Store app by running the following command:

    dotnet run --project ./Store/Store.csproj
    
  6. The browser opens a page that displays the homepage of the website. In the menu on the left, select Products to see the catalog obtained from the Web API.

  7. To stop debugging, close the browser, and press Ctrl+C in both terminals.

Add .NET Aspire to the Store web app

Now, let's enroll the Store project, which implements the web user interface, in .NET Aspire orchestration:

  1. In Visual Studio, in the Solution Explorer, right-click the Store project, select Add, and then select .NET Aspire Orchestrator Support.

  2. In the Add .NET Aspire Orchestrator Support dialog, select OK.

    Screenshot of the Add .NET Aspire Orchestrator Support dialog.

You should now have two new projects, both added to the solution:

  • eShopLite.AppHost: An orchestrator project designed to connect and configure the different projects and services of your app. The orchestrator is set as the Startup project, and it depends on the eShopLite.Store project.
  • eShopLite.ServiceDefaults: A .NET Aspire shared project to manage configurations that are reused across the projects in your solution related to resilience, service discovery, and telemetry.

In the eShopLite.AppHost project, open the Program.cs file. Notice this line of code, which registers the Store project in the .NET Aspire orchestration:

builder.AddProject<Projects.Store>("store");

For more information, see AddProject.

To add the Products project to .NET Aspire:

  1. In Visual Studio, in the Solution Explorer, right-click the Products project, select Add, and then select .NET Aspire Orchestrator Support.

  2. A dialog indicating that .NET Aspire Orchestrator project already exists, select OK.

    Screenshot indicating that the.NET Aspire Orchestrator was already added.

In the eShopLite.AppHost project, open the Program.cs file. Notice this line of code, which registers the Products project in the .NET Aspire orchestration:

builder.AddProject<Projects.Products>("products");

Also notice that the eShopLite.AppHost project, now depends on both the Store and Products projects.

Create an app host project

In order to orchestrate the existing projects, you need to create a new app host project. To create a new app host project from the available .NET Aspire templates, use the following .NET CLI command:

dotnet new aspire-apphost -o eShopLite.AppHost

Add the app host project to existing solution:

dotnet sln ./eShopLite.sln add ./eShopLite.AppHost/eShopLite.AppHost.csproj

Add the Store project as a project reference to the app host project using the following .NET CLI command:

dotnet add ./eShopLite.AppHost/eShopLite.AppHost.csproj reference ./Store/Store.csproj

Create a service defaults project

After the app host project is created, you need to create a new service defaults project. To create a new service defaults project from the available .NET Aspire templates, use the following .NET CLI command:

dotnet new aspire-servicedefaults -o eShopLite.ServiceDefaults

To add the project to the solution, use the following .NET CLI command:

dotnet sln ./eShopLite.sln add ./eShopLite.ServiceDefaults/eShopLite.ServiceDefaults.csproj

Update the app host project to add a project reference to the Products project:

dotnet add ./eShopLite.AppHost/eShopLite.AppHost.csproj reference ./Products/Products.csproj

Both the Store and Products projects need to reference the service defaults project so that they can easily include service discovery. To add a reference to the service defaults project in the Store project, use the following .NET CLI command:

dotnet add ./Store/Store.csproj reference ./eShopLite.ServiceDefaults/eShopLite.ServiceDefaults.csproj

The same command with slightly different paths should be used to add a reference to the service defaults project in the Products project:

dotnet add ./Products/Products.csproj reference ./eShopLite.ServiceDefaults/eShopLite.ServiceDefaults.csproj

In both the Store and Products projects, update their Program.cs files, adding the following line immediately after their var builder = WebApplication.CreateBuilder(args); line:

builder.AddServiceDefaults();

Update the app host project

Open the Program.cs file of the app host project, and replace its contents with the following C# code:

var builder = DistributedApplication.CreateBuilder(args);

builder.AddProject<Projects.Store>("store");

builder.AddProject<Projects.Products>("products");

builder.Build().Run();

The preceding code:

  • Creates a new DistributedApplicationBuilder instance.
  • Adds the Store project to the orchestrator.
  • Adds the Products project to the orchestrator.
  • Builds and runs the orchestrator.

Service Discovery

At this point, both projects are part of .NET Aspire orchestration, but the Store needs to be able to discover the Products backend address through .NET Aspire's service discovery. To enable service discovery, open the Program.cs file in eShopLite.AppHost and update the code that the Store adds a reference to the Products project:

var builder = DistributedApplication.CreateBuilder(args);

var products = builder.AddProject<Projects.Products>("products");

builder.AddProject<Projects.Store>("store")
       .WithExternalHttpEndpoints()
       .WithReference(products);

builder.Build().Run();

The preceding code expresses that the Store project depends on the Products project. For more information, see .NET Aspire app host: Reference resources. This reference is used to discover the address of the Products project. Additionally, the Store project is configured to use external HTTP endpoints. If you later choose to deploy this app, you'd need the call to WithExternalHttpEndpoints to ensure that it's public to the outside world.

Next, update the appsettings.json in the Store project with the following JSON:

{
  "DetailedErrors": true,
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ProductEndpoint": "http://products",
  "ProductEndpointHttps": "https://products"
}

The addresses for both the endpoints now uses the "products" name that was added to the orchestrator in the app host. These names are used to discover the address of the Products project.

Explore the enrolled app

Let's start the solution and examine the new behavior that .NET Aspire provides.

Note

Notice that the eShopLite.AppHost project is the new startup project.

  1. In Visual Studio, to start debugging, press F5 Visual Studio builds the projects.
  2. If the Start Docker Desktop dialog appears, select Yes. Visual Studio starts the Docker engine and creates the necessary containers. When the deployment is complete, the .NET Aspire dashboard is displayed.
  3. In the dashboard, select the endpoint for the products project. A new browser tab appears and displays the product catalog in JSON format.
  4. In the dashboard, select the endpoint for the store project. A new browser tab appears and displays the home page for the web app.
  5. In the menu on the left, select Products. The product catalog is displayed.
  6. To stop debugging, close the browser.

Delete the launch.json file that you created earlier, it no longer serves a purpose. Instead, start the app host project, which orchestrates the other projects:

  1. Start the app host project by right-clicking the eShopLite.AppHost project in the Solution Explorer and selecting Debug > Start New Instance:

    Visual Studio Code: Solution Explorer selecting Debug > Start New Instance.

    Note

    If Docker Desktop (or Podman) isn't running, you'll experience an error. Start the OCI compliant container engine and try again.

  1. Start the app host project by running the following command:

    dotnet run --project ./eShopLite.AppHost/eShopLite.AppHost.csproj
    

    Note

    If Docker Desktop (or Podman) isn't running, you'll experience an error. Start the OCI compliant container engine and try again.

  1. In the dashboard, select the endpoint for the products project. A new browser tab appears and displays the product catalog in JSON format.
  2. In the dashboard, select the endpoint for the store project. A new browser tab appears and displays the home page for the web app.
  3. In the menu on the left, select Products. The product catalog is displayed.
  4. To stop debugging, close the browser.

Congratulations, you added .NET Aspire orchestration to your pre-existing web app. You can now add .NET Aspire integrations and use the .NET Aspire tooling to streamline your cloud-native web app development.