https://github.com/viniciuscestarii/multi-tenant-dotnet-app
🌆 A sample multi-tenant application using ASP.NET Core and Entity Framework Core
https://github.com/viniciuscestarii/multi-tenant-dotnet-app
asp-net-core dotnet8 entity-framework-core multi-tenant postgresql
Last synced: 6 months ago
JSON representation
🌆 A sample multi-tenant application using ASP.NET Core and Entity Framework Core
- Host: GitHub
- URL: https://github.com/viniciuscestarii/multi-tenant-dotnet-app
- Owner: ViniciusCestarii
- License: mit
- Created: 2024-11-01T17:02:37.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-02-18T11:23:26.000Z (8 months ago)
- Last Synced: 2025-03-29T14:41:20.890Z (7 months ago)
- Topics: asp-net-core, dotnet8, entity-framework-core, multi-tenant, postgresql
- Language: C#
- Homepage:
- Size: 32.2 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Multi-Tenant .NET App
This is a sample multi-tenant application that demonstrates how to build a multi-tenant application using ASP.NET Core and Entity Framework Core.
## Features
- Tenant Resolution Strategy
###### CurrentTenantService.cs
```cs
var tenantInfo = await _context.Tenants.Where(x => x.Id == tenant).FirstOrDefaultAsync(); // check if tenant exists
if (tenantInfo != null)
{
TenantId = tenant;
ConnectionString = tenantInfo.ConnectionString; // optional connection string per tenant (can be null to use default database)
return true;
}
else
{
throw new Exception("Tenant invalid");
}
```
- Tenant Database Isolation if isolated = `true`
###### TenantService.cs
```cs
public Tenant CreateTenant(CreateTenantRequest request)
{
string newConnectionString = null;
if (request.Isolated == true)
{
// generate a connection string for new tenant database
string dbName = "MultiTenantAppDb-" + request.Id;
string defaultConnectionString = _configuration.GetConnectionString("DefaultConnection");
newConnectionString = defaultConnectionString.Replace("multi-tenant", dbName);
// create a new tenant database and bring current with any pending migrations from ApplicationDbContext
try
{
using IServiceScope scopeTenant = _serviceProvider.CreateScope();
ApplicationDbContext dbContext = scopeTenant.ServiceProvider.GetRequiredService();
dbContext.Database.SetConnectionString(newConnectionString);
if (dbContext.Database.GetPendingMigrations().Any())
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine($"Applying ApplicationDB Migrations for New '{request.Id}' tenant.");
Console.ResetColor();
dbContext.Database.Migrate();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
```
- EF Core Query Filters
###### ApplicationDbContext.cs
```cs
// On Model Creating - multitenancy query filter, fires once on app start
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity().HasQueryFilter(a => a.TenantId == CurrentTenantId);
}
```
- Swagger Open API

## Getting Started
To get started, clone the repository and run the following commands:
```bash
git clone https://github.com/ViniciusCestarii/Multi-Tenant-Dotnet-App.git
```
```bash
dotnet ef database update --context ApplicationDbContext
```
```bash
dotnet run
```
Now you can navigate to `http://localhost:5284/swagger/index.html` to try the application.
## Prerequisites
- .NET 8
- PostgreSQL
## Running with Docker
To run the application with Docker, you can use the following command:
```bash
docker-compose up
```
Don't forget to update the connection string in the `appsettings.json` file to point to the PostgreSQL container. (Server=db)
Now you can navigate to `http://localhost:5284/swagger/index.html` to try the application.