Overview
Multi-tenancy is a software architecture pattern where a single application instance serves multiple tenants on one server. The WeiChat framework implements this using a shared database, shared schema, and shared tables design.
Administrative Operations
The system administrator can access the tenant management interface to manage tenant members and bind administrator WeChat accounts.
The public account configuration interface allows administrators to set up WeChat public account information.
System administrators have privileges to manage both their own tenant data and other tenants' public account configurations.
Architecture Implementation
The framework implements multi-tenancy through three main steps:
- Establishing TenantId
- Extending ASP.NET Identity for multi-tenant support
- Registering tenant filters
Establishing TenantId
The tenant table structure is defined as follows:
public class TenantAccount
{
public int Id { get; set; }
public bool IsSystemTenant { get; set; }
[Required]
[MaxLength(20)]
public string Name { get; set; }
[DataType(DataType.MultilineText)]
[MaxLength(500)]
public string Description { get; set; }
}
The Id serves as the primary key and identity column, automatically generated by the database. All tenant-shared tables use the TenantId field to distinguish between differant tenants' data.
The base class design incorporates the tenant identifier:
public abstract class TenantEntityBase<TKey> : ITenantId, ICreatedBy, IModifiedBy
{
[Key]
public virtual TKey Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? ModifiedDate { get; set; }
[MaxLength(128)]
public string CreatedById { get; set; }
[ForeignKey("CreatedById")]
public ApplicationUser CreatedByUser { get; set; }
[MaxLength(128)]
public string ModifiedById { get; set; }
[MaxLength(256)]
public ApplicationUser ModifiedByUser { get; set; }
public int TenantId { get; set; }
}
The TenantId field serves as the data segregation boundary. In Code First approach, inheritance efficiently adds these fields to all model classes.
Extending ASP.NET Identity for Multi-Tenancy
The framework extends ASP.NET Identity through the Magicodes.WeiChat.Data.Multitenant library. The extension involves modifying key Identity components:
- IUser interface
- IdentityUser class
- IdentityDbContext
- IdentityUserLogin
- UserStore
Critical methods requiring override for multi-tenant support include:
- FindByNameAsync
- AddLoginAsync
- FindAsync
- FindByEmailAsync
- CreateAsync
Registering Tenant Filters
The framework utilizes EntityFramework.DynamicFilters for automatic data filtering. The tenant filter is defined as:
modelBuilder.Filter("TenantDataFilter",
(ITenantId entity, int tenantId) => entity.TenantId == tenantId, 0);
Filter activation and parameter setting:
dbContext.EnableFilter(filterName);
dbContext.SetFilterScopedParameterValue(filterName, "tenantId", currentTenantId);
This configuration can be encapsulated in common locations such as controller base classes' OnActionExecuting method.