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:
- Create the WebApplicationBuilder instance, and optionally configure the dependency injection container (not done in this example)
- Build the application, which returns a WebApplication instance
- Optionally configure the port(s) the application exposes
- Optionally configure any endpoints to expose on the above ports
- 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.
Create the
WebApplicationBuilder instance
:// create the main application builder var builder = WebApplication.CreateBuilder(args); // create the admin application builder var adminBuilder = WebApplication.CreateBuilder(args);
Build
the application:// main application var app = builder.Build(); // admin application var adminApp = adminBuilder.Build();
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");
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"; });
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 tohttp://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 tohttp://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.