Tutorial: Building Modular Multi-tenant ASP.NET Core Applications with Dotnettency

Part 4

This tutorial is part 4 in this series. The sample code to go with this post can be found here.

Published on 01 October 2017

In the previous tutorials we have seen how to configure an asp.net core application for multiple tenants, which included setting up the Moogle and Gicrosoft tenants. In this tutorial, we will allow each tenant to have it's own middleware pipeline. This allows us to precisely control which middlware runs for which tenants! This feature is sometimes referred to as Per Tenant Middleware in ASP.NET Core.

Per Tenant Middleware you say?

Suppose you have some middleware, like:

  • UseWelcomePage
  • UseMvc
  • UseBlah

Great! But your application is also used by multiple Tenants. You would like to enable the welcome page middleware for one of those tenants but not for the others! Let's see how the Dotnettency.MiddlewarePipeline nuget package is your friend!

Welcome Moogle!

We are goiing to call the UseWelcomePage() on an IApplicationBuilder to add the WelcomePage middleware - nothing unusual here. The only difference is, the IApplicationBuilder we call this on will be for the Moogle Tenant. The Gicrosoft tenant will remain unaffected.

  1. Ensure you have a Package Reference to Dotnettency.MiddlewarePipeline nuget package,
  2. In startup.cs in ConfigureServices() - find your call to AddMultiTenancy() as per the below:

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            return services.AddMultiTenancy<Tenant>((multiTenancyOptions) =>
            {
                multiTenancyOptions
                    .InitialiseTenant<TenantShellFactory>()
                    .ConfigureTenantContainers((containerBuilder)=> {
                        containerBuilder.WithStructureMap((tenant, tenantServices) =>
                        {

                        });
                    })
                    .ConfigureTenantMiddleware((tenantsMiddlewareBuilder) =>
                    {
                        tenantsMiddlewareBuilder.OnInitialiseTenantPipeline((context, appBuilder) =>
                        {
                           
                        });
                    });
            });
        }

  1. Inside ConfigureTenantMiddleware is where we can add any tenant specific middleware. If the above seems unfamiliar to you, please refer to the the previous tutorials. Let's add the WelcomePage middleware for the Moogle tenant:

                    .ConfigureTenantMiddleware((tenantsMiddlewareBuilder) =>
                    {
                        tenantsMiddlewareBuilder.OnInitialiseTenantPipeline((context, appBuilder) =>
                        {
                            if (context.Tenant.Name == "Moogle")
                            {
                                appBuilder.UseWelcomePage();
                            }
                        });
                    });                            

I won't cover the TenantShellFactory in this tutorial as it has already been covered previously. Suffice it to say that this class is responsible for identifying who the current Tenant is, based on the URL or any other accessible value. In our sample we have mapped localhost:5000 to the Moogle Tenant and localhost:5002 to Gicrosoft Tenant.

If we run the application, and browse on localhost:5000 (i.e Moogle) we get:

hellopagemiddleware.PNG

Success! That's a beautiful looking welcome page. Very blue.

If we browse our application on localhost:5002 we get:

error500.PNG

Hurray! This means our middleware is only running for the Tenant we wanted it to run for!

Furthermore, this works with any existing asp.net core Middleware today. The middleware does not have to be written with multitenancy in mind in any way.

What's next?

Have any multitenant scenarios you want me to cover for asp.net core? Let me know! Stay tuned for:

  1. Per Tenant IHostingEnvironment (each tenant has its own virtual file system)
  2. Modules (Shared and Routed)

Don't forget to leave a comment if you find this stuff useful!

comments powered by Disqus