I'm developing a multi-teant SaaS application in ASP.NET core mvc and I was wondering what the general approach is to applying tenant logic in a shared database scenario (TenantId for each entity). And more specificly, where this logic should be applied; In the Context, UnitOfWork, Repository or Service?
My current architecture looks like this:
EF DbContext -> UnitOfWork -> Repository -> Service
Right now, I'm applying all of my logic in the EF DbContext. For example applying the TenantId to a entity:
public override int SaveChanges( )
{
foreach ( var entityEntry in ChangeTracker.Entries( ) )
{
if ( entityEntry.Entity is ITenantEntity entity )
{
if ( entityEntry.State == EntityState.Added ||
entityEntry.State == EntityState.Modified )
{
entity.TenantId = _tenantProvider.GetTenantId( );
}
}
}
return base.SaveChanges( );
}
And filtering out data based on tenant:
protected override void OnModelCreating( ModelBuilder builder )
{
base.OnModelCreating( builder );
... omitted ....
builder.Entity<Person>( )
.HasQueryFilter( p => p.TenantId == _tenantProvider.GetTenantId( ) );
builder.Entity<Address>( )
.HasQueryFilter( p => p.TenantId == _tenantProvider.GetTenantId( ) );
builder.Entity<Company>( )
.HasQueryFilter( p => p.TenantId == _tenantProvider.GetTenantId( ) );
... omitted ....
}