Last active
February 2, 2023 19:17
New migration handler that came in v4.3.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
using Microsoft.Extensions.Logging; | |
using Volo.Abp.Data; | |
using Volo.Abp.DependencyInjection; | |
using Volo.Abp.EventBus.Distributed; | |
using Volo.Abp.Identity; | |
using Volo.Abp.MultiTenancy; | |
using Volo.Abp.Uow; | |
namespace Acme.BookStore.Data | |
{ | |
public class MyProjectNameTenantDatabaseMigrationHandler : | |
IDistributedEventHandler<TenantCreatedEto>, | |
IDistributedEventHandler<TenantConnectionStringUpdatedEto>, | |
IDistributedEventHandler<ApplyDatabaseMigrationsEto>, | |
ITransientDependency | |
{ | |
private readonly IEnumerable<IMyProjectNameDbSchemaMigrator> _dbSchemaMigrators; | |
private readonly ICurrentTenant _currentTenant; | |
private readonly IUnitOfWorkManager _unitOfWorkManager; | |
private readonly IDataSeeder _dataSeeder; | |
private readonly ITenantStore _tenantStore; | |
private readonly ILogger<MyProjectNameTenantDatabaseMigrationHandler> _logger; | |
public MyProjectNameTenantDatabaseMigrationHandler( | |
IEnumerable<IMyProjectNameDbSchemaMigrator> dbSchemaMigrators, | |
ICurrentTenant currentTenant, | |
IUnitOfWorkManager unitOfWorkManager, | |
IDataSeeder dataSeeder, | |
ITenantStore tenantStore, | |
ILogger<MyProjectNameTenantDatabaseMigrationHandler> logger) | |
{ | |
_dbSchemaMigrators = dbSchemaMigrators; | |
_currentTenant = currentTenant; | |
_unitOfWorkManager = unitOfWorkManager; | |
_dataSeeder = dataSeeder; | |
_tenantStore = tenantStore; | |
_logger = logger; | |
} | |
public async Task HandleEventAsync(TenantCreatedEto eventData) | |
{ | |
await MigrateAndSeedForTenantAsync( | |
eventData.Id, | |
eventData.Properties.GetOrDefault("AdminEmail") ?? MyProjectNameConsts.AdminEmailDefaultValue, | |
eventData.Properties.GetOrDefault("AdminPassword") ?? MyProjectNameConsts.AdminPasswordDefaultValue | |
); | |
} | |
public async Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData) | |
{ | |
if (eventData.ConnectionStringName != ConnectionStrings.DefaultConnectionStringName || | |
eventData.NewValue.IsNullOrWhiteSpace()) | |
{ | |
return; | |
} | |
await MigrateAndSeedForTenantAsync( | |
eventData.Id, | |
MyProjectNameConsts.AdminEmailDefaultValue, | |
MyProjectNameConsts.AdminPasswordDefaultValue | |
); | |
/* You may want to move your data from the old database to the new database! | |
* It is up to you. If you don't make it, new database will be empty | |
* (and tenant's admin password is reset to 1q2w3E*). | |
*/ | |
} | |
public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData) | |
{ | |
if (eventData.TenantId == null) | |
{ | |
return; | |
} | |
await MigrateAndSeedForTenantAsync( | |
eventData.TenantId.Value, | |
MyProjectNameConsts.AdminEmailDefaultValue, | |
MyProjectNameConsts.AdminPasswordDefaultValue | |
); | |
} | |
private async Task MigrateAndSeedForTenantAsync( | |
Guid tenantId, | |
string adminEmail, | |
string adminPassword) | |
{ | |
try | |
{ | |
using (_currentTenant.Change(tenantId)) | |
{ | |
// Create database tables if needed | |
using (var uow = _unitOfWorkManager.Begin(requiresNew: false, isTransactional: false)) | |
{ | |
var tenantConfiguration = await _tenantStore.FindAsync(tenantId); | |
if (tenantConfiguration?.ConnectionStrings != null && | |
!tenantConfiguration.ConnectionStrings.Default.IsNullOrWhiteSpace()) | |
{ | |
foreach (var migrator in _dbSchemaMigrators) | |
{ | |
await migrator.MigrateAsync(); | |
} | |
} | |
await uow.CompleteAsync(); | |
} | |
// Seed data | |
using (var uow = _unitOfWorkManager.Begin(requiresNew: false, isTransactional: true)) | |
{ | |
await _dataSeeder.SeedAsync( | |
new DataSeedContext(tenantId) | |
.WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, adminEmail) | |
.WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, adminPassword) | |
); | |
await uow.CompleteAsync(); | |
} | |
} | |
} | |
catch (Exception ex) | |
{ | |
_logger.LogException(ex); | |
} | |
} | |
} | |
} |
I don't know whether this solution work for anybody, I'm new in abp angular and the create tenant modal form save button is even disabled. How will I go around it?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You need to put this class into
/aspnet-core/src/Acme.BookStore/Domain/Data/
directory.