Tenantry Pro

Provisioning, migrations across tenant databases, and tenant-aware operations. Pro builds on the open-source Tenantry Core, which stays free and covers resolving tenants and isolating their data on its own.

Onboard a tenant

One call creates the tenant’s database or schema, applies your migrations and runs your seeders, in order. The result reports each step: succeeded, failed, skipped or not run. Every built-in step is safe to repeat, so a failed onboarding is retried by running it again.

Tenant lifecycle
TenantOnboarding.cs
tenant.UsePro(pro => pro
    .AddSeeder<DefaultDataSeeder>()               // your seeder, last
    .AddDatabaseProvisioning<AppDbContext>()      // creates the database, first
    .AddMigrations<AppDbContext>());              // then migrates it

var result = await provisioner.ProvisionAsync(descriptor, ct);
if (result.Succeeded)
    await tenants.ActivateAsync(descriptor.TenantId, ct);

Keep every tenant database migrated

Run your application with migrate-tenants as a deployment step: it applies the pending EF Core migrations to every tenant’s database or schema, one at a time or several at once, each once however many tenants share it. One database’s failure does not stop the others; each is logged, and the step fails so the release waits. The status is readable without migrating.

Tenant migrations
Program.cs
await using var app = builder.Build();

// dotnet run -- migrate-tenants
if (await app.RunTenantMigrationsIfRequestedAsync(args) is { } exitCode)
    return exitCode;   // 1 if any database or schema failed

await app.RunAsync();
return 0;

Run background work as the tenant

A Hangfire job, a Quartz.NET job, or a MassTransit or Rebus message carries the tenant it was created for, and runs as that tenant, with its DbContext isolated as in a request. Recurring work can run once for each tenant. A job whose tenant no longer exists is rejected rather than run as nobody.

Background jobs
Program.cs
tenant.UsePro(pro => pro.AddHangfirePropagation());

builder.Services.AddHangfire((sp, config) => config
    .UseSqlServerStorage(connectionString)
    .UseTenantry(sp));

// Runs as the current tenant, or as the one you name:
jobs.ForTenant(tenantId).Enqueue<ReportJob>(job => job.Execute());

Before you buy

What does the subscription include?
Every Tenantry Pro package, from a private NuGet feed, with each release while the subscription lasts, a licence key, and email support. One subscription, billed monthly or yearly: no tiers or seats.
How do I install it, locally and in CI?
Connect your GitHub account on your Pro access page, then add the feed to a nuget.config with a read-only GitHub token. In CI the token is a secret, and so is the licence key; the installation guide has the steps for GitHub Actions and Docker builds. Installation
Which versions and databases?
.NET 8, 9 and 10, with the EF Core of each. Provisioning and migrations on SQL Server, PostgreSQL and MySQL; schema per tenant on SQL Server and PostgreSQL. Compatibility
Does it phone home?
No. The licence key is checked offline when the application starts, and it does not expire. Licensing
What happens when the subscription ends?
The versions you have keep working, under the licence: the key keeps validating. Your access to the package feed ends, so keep copies of the packages you build with, in an internal feed or a local package folder, until you subscribe again.