What is Multitenancy?
A multitenant focuses on sharing these components fully or partially among the users.
In Addition, the application tier is usually scaled up vertically by adding more resources depending on the tenant’s preference and data usage volume.
Why Multitenancy?
For example,
One of the famous sneakers company has multiple branches called Branch A, Branch B, and Branch C. Each branch have its own inventory and budget.
Traditional Approach is to install a standalone app instance for each branch. In future, if you have extra branches D and E then we will deploy new branches same as old. But this is highly not efficient as there is no comman functional change in all these instances of the app.
Multitenancy Approach where each branch is a tenant with its own dataset. This allows the installation of the software once in a single location and scales up with new branches
Let’s assume Branch A runs with large Inventory and heavy workload whereas Branch B and Branch C operate with low budgets and few inventories. So, a shared database is a cost-effective choice for Branch B and Branch C.
You can better understand with below diagrams,

Let's start with practical implementation,
Create Domain Class with primary key with tenant id.
public abstract class BaseEntity
{
public int Id { get; set; }
public string TenantId { get; set; }
}
The inventory class:
public class Inventory: BaseEntity
{
public string Name { get; set; }
public decimal Price { get; set; }
}
To define the necessary settings and data for tenants below model is very useful.
public class Tenant
{
public string Name { get; set; }
public string Password { get; set; }
public string ConnectionString { get; set; }
}
public class User
{
public string Name { get; set; } = null!;
public string Password { get; set; } = null!;
public string TenantId { get; set; } = null!;
}
public class TenantScales
{
public string? DefaultConnection { get; set; }
public Tenant[] Tenants { get; set; } = Array.Empty<Tenant>();
public User[] Users { get; set; } = Array.Empty<User>();
}
Here is the configuration file,
{
"AllowedHosts": "*",
"TenantScales": {
"DefaultConnection": "Data Source=DESKTOP-60RDDSL;Initial Catalog=SneakersInventory;Integrated Security=True;MultipleActiveResultSets=True",
"Tenants": [
{
"Name": "SneakersInventoryBranchA",
"ConnectionString": "Data Source=DESKTOP-60RDDSL;Initial Catalog=SneakersInventoryBranchA;Integrated Security=True;MultipleActiveResultSets=True"
},
{
"Name": "SneakersInventoryBranchB",
"ConnectionString": "Data Source=DESKTOP-60RDDSL;Initial Catalog=SneakersInventoryBranchBC;Integrated Security=True;MultipleActiveResultSets=True"
},
{
"Name": "SneakersInventoryBranchC",
"ConnectionString": "Data Source=DESKTOP-60RDDSL;Initial Catalog=SneakersInventoryBranchBC;Integrated Security=True;MultipleActiveResultSets=True"
}
],
"Users": [
{
"Name": "SneakersInventoryBranchA-User",
"Password": "SneakersInventoryBranchA-Password",
"TenantId": "SneakersInventoryBranchA"
},
{
"Name": "SneakersInventoryBranchB-User",
"Password": "SneakersInventoryBranchB-Password",
"TenantId": "SneakersInventoryBranchB"
},
{
"Name": "SneakersInventoryBranchC-User",
"Password": "SneakersInventoryBranchC-Password",
"TenantId": "SneakersInventoryBranchC"
}
]
}
}
Here we have Users as well as tenants with its connection strings. tenant defines branches of sneakers shops.
Implement TenantRegistry method from ITenantRegistry interface.
namespace SneakersApplication.Infrastructure;
public class TenantRegistry: ITenantRegistry {
private readonly TenantScales _tenantScales;
public TenantRegistry(IConfiguration configuration) {
_tenantScales = configuration.GetSection("TenantScales").Get < TenantScales > ();
foreach(var tenant in _tenantScales.Tenants.Where(e => string.IsNullOrEmpty(e.ConnectionString))) {
tenant.ConnectionString = _tenantScales.DefaultConnection;
}
}
public Tenant[] GetTenants() => _tenantScales.Tenants;
public User[] GetUsers() => _tenantScales.Users;
}
Implement TenantResolver method from ITenantResolver interface



Join the conversation! Your thoughts help the community grow.