Multiple applications - one host

How multiple applications can be run in a single ASPNET Core host with minimal api

Home DailyDrop

Daily Knowledge Drop

Multiple applications can be executed inside a single ASPNET Core host - this effectively allows different endpoints and functionality to be available on the same base URL, but with different ports.

I first learnt about this in Khalid Abuhakmeh's post on the subject, however his post dives into using the IHostBuilder (the technique prior to .NET6's top level statement and minimal api model). This post explores how to achieve the same output, but with the .NET6 WebApplicationBuilder, top level statements and minimal api.


Single application

First let's look at the default host setup with a single application:

// Create the builder
var builder = WebApplication.CreateBuilder(args);

// create the app from the builder
var app = builder.Build();

// optionally set the port
app.Urls.Add("http://*:5001");

// define endpoints to expose on the port
app.MapGet("/main", () =>
{
    return "Welcome to the main application";
});

// run the application
await app.RunAsync();

There are a number of steps to configuring an application for startup:

  1. Create the WebApplicationBuilder instance, and optionally configure the dependency injection container (not done in this example)
  2. Build the application, which returns a WebApplication instance
  3. Optionally configure the port(s) the application exposes
  4. Optionally configure any endpoints to expose on the above ports
  5. Run the application

To create multiple applications, basically these steps need to be duplicated, with some slight changes.


Multiple applications

Startup

In our sample, we are going to create two applications to be hosted - a main application, which would expose business related endpoints, and an admin application which exposes admin related endpoints. This setup is just for demo purposes - I wouldn't necessarily recommend this setup for a production application as a default.

Let's start at the top and duplicate the configuration.

  1. Create the WebApplicationBuilder instance:

    // create the main application builder
    var builder = WebApplication.CreateBuilder(args);
    // create the admin application builder
    var adminBuilder = WebApplication.CreateBuilder(args);
    
  2. Build the application:

    // main application
    var app = builder.Build();
    // admin application
    var adminApp = adminBuilder.Build();
    
  3. Configure the port(s) the applications each expose:

    // the main application's endpoints will be exposed 
    // on port 5001
    app.Urls.Add("http://*:5001");
    // the admin endpoints will be exposed 
    // on port 5009
    adminApp.Urls.Add("http://*:5009");
    
  4. Configure any endpoints to be exposed:

    // exposed the main application endpoints
    app.MapGet("/main", () =>
    {
        return "Welcome to the main application";
    });
    
    // expose the admin endpoints
    adminApp.MapGet("/admin", () =>
    {
        return "Welcome to the admin application";
    });
    
  5. Run the application:

    // as we have multiple applications running
    // we execute both of them and wait for either
    // to finish before shutting down the host
    await Task.WhenAny(
        app.RunAsync(),
        adminApp.RunAsync()
    );
    

Execution

Running the project/host now:

  • Expose main application functionality on port 5001. Browsing to http://localhost:5001/main will return:

    Welcome to the main application
    

    While trying to access the admin endpoint on the main application port 5001 will not return any results.

  • Expose admin functionality on port 5009. Browsing to http://localhost:5009/admin will return:

    Welcome to the admin application
    

    While trying to access the main endpoint on the admin application port 5009 will not return any results.


Notes

While not something I would recommend as the default go-to method, the ability to segregate endpoints into completely separate applications can prove useful in certain use cases - such as separating business and admin functionality as demonstrated in the example or if running a multi-tenant application, another use case could to separate each tenant into their own application (and own ports). However there are probably better ways than creating multiple applications in one host for both the above mentioned use cases - but the knowledge the this is possible, is another tool to potentially use when required.


References

Hosting Two ASP.NET Core Apps In One Host


Daily Drop 126: 28-07-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net host api