-
Notifications
You must be signed in to change notification settings - Fork 161
Building a tenant change service
The AuthP tenant admin has methods to create, change, delete and so on a tenant for you. But when one of these tenant admin methods are called you need you nearly always need to apply a change the tenant's data, for instance if you delete a tenant you would expect all the tenant's data should be deleted too. The solution is to create a class that follows the ITenantChangeService
and I refer to this class as a tenant change service.
Its not a trivial task to create a tenant change service, but there are many examples (currently 3) in the AuthP repo which should help you. This document starts with the why and the design of tenant change service and then covers each of the example implementation of the ITenantChangeService
interface.
NOTE: Remember that you need to register your tenant change service during the registering the AuthP in your ASP.NET Core - see Registering your tenant change service section in the Multi tenant configuration document.
The ITenantChangeService
interface defines various methods which are called from the tenant admin once the AuthP's Tenant entity as been updated. Then the correct in your registered tenant change service is called. At the end of this process the AuthP's Tenant entity will be changed and your tenant change service has the necessary changes to the tenant's data.
To ensure that the two changes are in step the tenant admin method calls your tenant change service method within a transaction. This means if your tenant change service method fails then both database's changes are rolled back. The diagram below shows how translations within the AuthP DbContext and the tenant data DbContext ensures that the two DbContext are in step.
There are six multi-tenant types implementation of the ITenantChangeService
(NOTE: The last two are referred as hybrid). They are:
TenantType |
num databases | num tenants per db | Example change service |
---|---|---|---|
SingleLevel | one database | many | see InvoiceTenantChangeService |
HierarchicalTenant | one database | many | see RetailTenantChangeService |
SingleLevel | many databases | one (Sharding) | see ShardingSingleDbContext |
HierarchicalTenant | many databases | one (Sharding) | |
SingleLevel | many databases | many & one (Hybrid) | see ShardingSingleDbContext |
HierarchicalTenant | many databases | many & one (Hybrid) |
The ITenantChangeService
has methods to cover all these six multi-tenant types, but you only need to implement the methods that your type needs. See each method and when it is called and what it has to do.
This will provide you with a tenant DbContext to access your tenant data. There are two options
- For the "one database" types you can inject your tenant DbContext to use in this service. This service won't have the correct DataKey, so you will use the
IgnoreQueryFilters
method and then use a where clause to select the correct tenant data. - For the "many databases" types you should inject the
DbContextOptions<YourTenantDbContext>
. Using this and the DataKey found in the method's properties you can then create a tenant DbContext to use.
This is called on the creation of a new tenant. Its job is to set up any tenant data you need added to the tenant DbContext, for instance in Example3 the tenant DbContext has a entity called CompanyTenant
which is used to display the name of the tenant.
NOTES:
- For the many databases multi-tenant types you should migrate the database if it hasn't been used yet. See ShardingSingleDbContext example.
- If the AuthP's Tenant's
HasOwnDb
is true, then its worth checking that there's other tenant data in the database
This is called when the tenant's name is changed. This allows to update any entities in the tenant DbContext which contains the name.
This is called to delete all of the tenant's data. A delete of tenant's data when there are other tenants can be tricky to write as you need to take account of the relationships and you can't just reset all the tables.
This is called when the tenant's name is changed, but in a hierarchical multi-tenant structure the renaming of a tenant requires the renaming of any children tenants. Therefore this method takes in a list of all the AuthP Tenants that were changed.
This is called when a tenant, and its children need to be deleted in AuthP and you need to delete data in the tenant's DbContext. Therefore this method takes in a list of all the AuthP Tenants that should be deleted, which are ordered with lowest child tenants first.
This moves a tenant to a new level in the hierarchical data - see this section for a good definition and diagram. To do this you work through the list AuthP's Tenants and change the DataKey of the tenant DbContext entities.
This moves the data in one database to another database. Usually you do this to change a tenant from "many per db" to "one per db". This is very complex and you might not want to provide this feature - see the ShardingTenantChangeService tenant change service with implements this, but on a simple database.
NOTES:
- You should migrate the database if the database hasn't been used yet. See ShardingSingleDbContext example.
- If the AuthP's Tenant's
HasOwnDb
is true, then its worth checking that there's other tenant data in the database
- Intro to multi-tenants (ASP.NET video)
- Articles in date order:
- 0. Improved Roles/Permissions
- 1. Setting up the database
- 2. Admin: adding users and tenants
- 3. Versioning your app
- 4. Hierarchical multi-tenant
- 5. Advanced technique with claims
- 6. Sharding multi-tenant setup
- 7. Three ways to add new users
- 8. The design of the sharding data
- 9. Down for maintenance article
- 10: Three ways to refresh claims
- 11. Features of Multilingual service
- 12. Custom databases - Part1
- Videos (old)
- Authentication explained
- Permissions explained
- Roles explained
- AuthUser explained
- Multi tenant explained
- Sharding explained
- How AuthP handles sharding
- How AuthP handles errors
- Languages & cultures explained
- JWT Token refresh explained
- Setup Permissions
- Setup Authentication
- Startup code
- Setup the custom database feature
- JWT Token configuration
- Multi tenant configuration
- Using Permissions
- Using JWT Tokens
- Creating a multi-tenant app
- Supporting multiple languages
- Unit Test your AuthP app