Multi-Tenancy Strategies
There are three main approaches: separate databases, shared database with schema, and shared schema with tenant ID. Each has trade-offs.
Tenant Resolution Middleware
public class TenantMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext ctx, ITenantService tenants)
{
var host = ctx.Request.Host.Host;
var tenant = await tenants.ResolveAsync(host);
ctx.Items["Tenant"] = tenant;
await next(ctx);
}
}
Scoped DbContext per Tenant
services.AddDbContext<AppDbContext>((sp, opts) =>
{
var tenant = sp.GetRequiredService<ITenantContext>();
opts.UseSqlServer(tenant.ConnectionString);
});
âš ï¸
Always validate tenant context before executing queries. A missing tenant check can expose one tenant's data to another.
Conclusion
Start with shared schema + tenant ID for simplicity. Migrate to separate databases only when isolation requirements demand it.