Tenantry.Pro documentation
Tenantry isolates tenants in a shared database or gives each tenant its own database. Tenantry.Pro extends it with a schema per tenant and mixed mode, and the operational tooling that many tenant databases require: provisioning, migration orchestration, a tenant-creation lifecycle, connection-string caching and encryption, audit logging, health checks, telemetry, and tenant-context propagation into background jobs and message buses.
Tenantry.Pro always sits inside a Tenantry core registration: you call AddTenantry (or
AddTenantryCore for non-HTTP hosts), keep your resolution and tenant store exactly as core defines
them, and add tenant.UsePro(pro => { ... }). Pro changes how each tenant's data is isolated and
operated — not how tenants are identified or stored.
If you are new, start with Installation, then Getting started.
Guides
Foundations
- Installation — the private package feed, its credentials, CI, and the licence key.
- Getting started — install the packages and build a database-per-tenant app end to end.
- Licensing — the offline ES256 licence key, which does not expire, and the startup check.
Isolation strategies
- Database per tenant — connection-string resolution, async resolvers, caching, and on-demand database provisioning.
- Schema per tenant — schema-name resolution, EF Core per-schema model caching, and schema provisioning.
- Mixed mode — routing individual tenants to a database, a schema, or the shared store.
- Connection-string encryption — encrypting cached connection strings at rest (AES, custom, or ASP.NET Core Data Protection).
- Database providers — SQL Server, PostgreSQL, and MySQL/MariaDB capabilities and differences.
Operations
- Migration orchestration — applying EF Core migrations across every tenant database, with per-tenant failure isolation and status tracking.
- Tenant lifecycle — the provision → migrate → seed pipeline and
ITenantSeeder. - Audit logging — recording entity changes per tenant via an EF Core interceptor.
- Health checks — verifying tenant database connectivity and pending migrations.
- Telemetry — per-tenant request metrics and the
Tenantry.Prometer.
Background work & messaging
- Background jobs & non-HTTP hosts —
ITenantScopeFactoryfor workers, console apps, and hosted services. - Hangfire, MassTransit, Quartz.NET, Rebus — tenant-context propagation across each library.
Reference
- Compatibility — supported .NET, EF Core, database and library versions, and dependency ranges.
- Troubleshooting — common pitfalls, AOT/trimming, and how to diagnose them.
- API reference — every public type and member, generated from the XML documentation comments.
How the pieces fit together
Tenantry core answers who is the tenant? and which tenants exist?. Tenantry.Pro adds three more
responsibilities, all configured inside the tenant.UsePro(...) lambda:
| Responsibility | Question it answers | Configured with |
|---|---|---|
| Licence | Is this deployment licensed for Pro features? | pro.WithLicence(key) |
| Isolation strategy | Where does this tenant's data physically live? | pro.UseDatabasePerTenant(...), pro.UseSchemaPerTenant(...), pro.UseMixedMode(...) |
| Operations & integrations | How are tenant databases provisioned, migrated, observed, and propagated into background work? | pro.AddDatabaseProvisioning(), pro.WithMigrationOrchestration(...), pro.AddLifecycleManagement(), pro.AddAuditLogging(), pro.AddTenantMetrics(), pro.AddHangfireTenantFilter(), … |
A database-per-tenant request flows like this:
HTTP request
│
▼
UseTenantry() ──► Tenantry core resolves the tenant and opens the tenant scope
│
▼
AddDbContext factory ──► ITenantConnectionStringResolver<TKey>.Resolve() ──► per-tenant connection string
│ (optionally cached, optionally encrypted at rest)
▼
Your endpoint + EF Core ──► reads and writes hit the tenant's own databaseFor schema-per-tenant the connection string is shared and the tenant's schema is applied in
OnModelCreating, with EF Core caching one compiled model per schema. In a console or worker app
there is no request, so you open the tenant scope yourself with ITenantScopeFactory<TKey> —
everything below the scope line behaves identically.
What Tenantry.Pro does not do
- It does not register your
DbContextfor you — you keep full control ofAddDbContext. - It does not invent your connection strings or schema names — you supply the delegates.
- It does not provision or migrate tenants automatically on first request — provisioning and
migration are explicit: run them as a deployment step, or at startup when you opt in with
runAtStartup: true. - It does not replace Tenantry core's resolution, storage, or row-level isolation — it composes with them.
- It does not provide an admin dashboard or UI.
TenantModelBuilderExtensions class
Extension methods for ModelBuilder that apply tenant isolation to all entities implementing ITenantScoped<TKey>tenantry-core-itenantscoped.md.
Installation
Tenantry.Pro's packages are published to a private GitHub Packages feed owned by the tenantry-org GitHub organisation.