AspNet Core 3.1 Nested Applications

This is a follow up on a previous post about how to host multiple isolated ASP.NET core applications in a single process with with a single http listener/entry. The techniques used in that post used types and classes e.g. Microsoft.AspNetCore.Hosting.Internal.StartupLoader that have been made internal in ASP.NET Core 3.x and thus the approach is no longer viable.

Instead we need to take a different approach that, while has some caveats, works well.

The gist of the solution is:

Nested Apps

  • Host each web application on their own independent WebHost with their own HTTP listener on loopback/localhost.

  • Run a reverse proxy server (ProxyKit today, or Microsoft's Reverse Proxy in the future) on a non-loopback IP address and configure it to forward requests for matching routes to each application.

However there are various defaults in AspNetCore will assume that it is the host and entry point. There are a number of things we need to do to make our ASP.NET Core web applications more "library" like so they can be composed and hosted.

  • Consider where and how static content is discovered depending on execution scenario (dotnet run/F5 vs Tests(ncrunch) vs dotnet publish).

  • Ensure each ASP.NET Core web application doesn't discover controllers, services, etc from the other web applications and register things it shouldn't know about.

  • Ensure the web applications bind to a random port so not to clash with any other process that might be using the same port.

  • Use typed settings for configuration and only use IConfiguration in the MainHost.

  • Any Security considerations i.e. other applications on the same machine should not be able to make HTTP requests to the applications listening on localhost.

Rather than go into details here, I've posted a complete runnable sample on GitHub that addresses all of the above and with more details in the implementation notes in the readme.