Wednesday, November 2, 2022

The multi-tenant Frontend case study with ASP.Net stack

 


This part of my book delves into an example of writing an ASP.Net Application with multi-tenancy. One of the very common asks is for an application to be made available in a different appearance for another business in the parent organization’s portfolio. Occasionally, this business might have its own active directory domain and missing federation. 

The choice of technology stack only affects the development of the software since multi-tenancy is an architectural decision. If they were different applications for each business, they could implement independent technology stacks regardless of whether the data provider services, and store are common to the businesses. When there is a user interface involved, the technology stack leans towards write-once-run-anywhere paradigm. ASP.Net fits this bill very well because it separates the client and the server code very well. The client code can be developed to suit all platforms – mobile, web, native mobile and native desktop. Web workers and server-side rendering makes it super-fast and bring security and performance to the server. Finally, ASP.Net is developer friendly in that it has simple constructs for model-view-controller and templates can be used in views. This makes it easy to get functionality right out of the box and spend less time making code work. 

The switch between single tenancy to multi-tenancy is handled by a few components within an ASP.Net application. First, there is a request interceptor that sets the appropriate tenant in the context. Second, this must be communicated to the server part of the application. Finally, the tenant-based customizations, automatic injection of services specific to the tenant domain, and reconfiguration of routes and redirects as per the domain of the tenant and a few other features must be enabled. 

The URLs for the tenant-specific domain name hosted services usually follow a pattern that can be made well-known across the application code base so that the same code works for every tenant. If the pattern and the whitelisting must be avoided, the tenant information can be persisted and looked up as an alternative from a tenant registry. ASP.Net defines an ApplicationDBContext and a service so these are added to the service. 

Then there will be methods provided for each of the following in the service: translation of the hostname/domain name to the tenant, adding a tenant information specifying header to the set of headers on the incoming request and defining enumerations of the tenants if the resolution is based on pattern and literal matching. 

The server side of the application will resolve multi-tenancy and inject custom services based on different database contexts. The extensions serve this purpose. It must resolve the connection string based on the domain name of the tenant. The connection string is passed to the ApplicationDBContext and a custom service for that domain is then added to the Service collections. A dedicated service, say one for logins, will be created for the tenant to target Active Directory and the domains can be maintained independently for each tenant within the same Active Directory instance.

The login service cannot typically be injected directly like the custom service for the custom DB context in the server startup code. Instead, the AddDefaultIdentity method is invoked on the service collection and supplied with the default user interface and entity framework store.  Similarly, the service collection must be initialized with a pattern for the controller and view resolutions such as with MVC.

No comments:

Post a Comment