refactor: 重构多租户模块,优化上线
This commit is contained in:
@@ -6,6 +6,7 @@ using Volo.Abp;
|
||||
using Volo.Abp.Application.Dtos;
|
||||
using Volo.Abp.Data;
|
||||
using Volo.Abp.Modularity;
|
||||
using Volo.Abp.Uow;
|
||||
using Yi.Framework.Ddd.Application;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
using Yi.Framework.TenantManagement.Application.Contracts;
|
||||
@@ -113,6 +114,7 @@ namespace Yi.Framework.TenantManagement.Application
|
||||
[HttpPut("tenant/init/{id}")]
|
||||
public async Task InitAsync([FromRoute] Guid id)
|
||||
{
|
||||
await CurrentUnitOfWork.SaveChangesAsync();
|
||||
using (CurrentTenant.Change(id))
|
||||
{
|
||||
await CodeFirst(this.LazyServiceProvider);
|
||||
@@ -124,10 +126,20 @@ namespace Yi.Framework.TenantManagement.Application
|
||||
private async Task CodeFirst(IServiceProvider service)
|
||||
{
|
||||
var moduleContainer = service.GetRequiredService<IModuleContainer>();
|
||||
var db = await _repository.GetDbContextAsync();
|
||||
|
||||
//尝试创建数据库
|
||||
db.DbMaintenance.CreateDatabase();
|
||||
//没有数据库,不能创工作单元,创建库,先关闭
|
||||
ISqlSugarClient db = null;
|
||||
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
|
||||
{
|
||||
db = await _repository.GetDbContextAsync();
|
||||
//尝试创建数据库
|
||||
db.DbMaintenance.CreateDatabase();
|
||||
await uow.CompleteAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
List<Type> types = new List<Type>();
|
||||
foreach (var module in moduleContainer.Modules)
|
||||
@@ -135,6 +147,7 @@ namespace Yi.Framework.TenantManagement.Application
|
||||
types.AddRange(module.Assembly.GetTypes()
|
||||
.Where(x => x.GetCustomAttribute<IgnoreCodeFirstAttribute>() == null)
|
||||
.Where(x => x.GetCustomAttribute<SugarTable>() != null)
|
||||
.Where(x=>x.GetCustomAttribute<DefaultTenantTableAttribute>() is null)
|
||||
.Where(x => x.GetCustomAttribute<SplitTableAttribute>() is null));
|
||||
}
|
||||
if (types.Count > 0)
|
||||
|
||||
@@ -93,24 +93,8 @@ namespace Yi.Framework.TenantManagement.Domain
|
||||
|
||||
private ConnectionStrings? MaptoString(string tenantConnectionString)
|
||||
{
|
||||
|
||||
//tenantConnectionString = tenantConnectionString.TrimEnd(';');
|
||||
//var strSpiteds = tenantConnectionString.Split(";");
|
||||
//if (strSpiteds.Count() == 0)
|
||||
//{
|
||||
// return null;
|
||||
|
||||
//}
|
||||
|
||||
var connectionStrings = new ConnectionStrings();
|
||||
//foreach (string strSpited in strSpiteds)
|
||||
//{
|
||||
// var key = strSpited.Split('=')[0];
|
||||
// var value = strSpited.Split('=')[1];
|
||||
// connectionStrings[key] = value;
|
||||
//}
|
||||
connectionStrings["test"] = tenantConnectionString;
|
||||
|
||||
connectionStrings[ConnectionStrings.DefaultConnectionStringName] = tenantConnectionString;
|
||||
return connectionStrings;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
namespace Yi.Framework.TenantManagement.Domain
|
||||
{
|
||||
[SugarTable("YiTenant")]
|
||||
[MasterTenant]
|
||||
[DefaultTenantTable]
|
||||
public class TenantAggregateRoot : FullAuditedAggregateRoot<Guid>, IHasEntityVersion
|
||||
{
|
||||
public TenantAggregateRoot()
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
using Volo.Abp.MultiTenancy;
|
||||
using Volo.Abp.Data;
|
||||
using Volo.Abp.MultiTenancy;
|
||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||
|
||||
namespace Yi.Framework.TenantManagement.Domain
|
||||
{
|
||||
public static class TenantManagementExtensions
|
||||
{
|
||||
public static IDisposable ChangeMaster(this ICurrentTenant currentTenant)
|
||||
{
|
||||
return currentTenant.Change(null, DbConnOptions.MasterTenantName);
|
||||
}
|
||||
|
||||
public static IDisposable ChangeDefalut(this ICurrentTenant currentTenant)
|
||||
{
|
||||
return currentTenant.Change(null, DbConnOptions.DefaultTenantName);
|
||||
return currentTenant.Change(null, ConnectionStrings.DefaultConnectionStringName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,16 @@ public class YiMultiTenantConnectionStringResolver : DefaultConnectionStringReso
|
||||
var tenantDefaultConnectionString = tenant.ConnectionStrings?.Default;
|
||||
|
||||
//Requesting default connection string...
|
||||
//if (connectionStringName == null ||
|
||||
// connectionStringName == ConnectionStrings.DefaultConnectionStringName)
|
||||
//{
|
||||
// //Return tenant's default or global default
|
||||
// return !tenantDefaultConnectionString.IsNullOrWhiteSpace()
|
||||
// ? tenantDefaultConnectionString!
|
||||
// : Options.ConnectionStrings.Default!;
|
||||
//}
|
||||
if (connectionStringName == null ||
|
||||
connectionStringName == ConnectionStrings.DefaultConnectionStringName)
|
||||
{
|
||||
//Return tenant's default or global default
|
||||
return !tenantDefaultConnectionString.IsNullOrWhiteSpace()
|
||||
? tenantDefaultConnectionString!
|
||||
: Options.ConnectionStrings.Default!;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Requesting specific connection string...
|
||||
var connString = tenant.ConnectionStrings?.FirstOrDefault().Value;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.MultiTenancy.Localization;
|
||||
|
||||
namespace Volo.Abp.MultiTenancy;
|
||||
|
||||
[Dependency(ReplaceServices =true)]
|
||||
public class YiTenantConfigurationProvider : ITenantConfigurationProvider, ITransientDependency
|
||||
{
|
||||
protected virtual ITenantResolver TenantResolver { get; }
|
||||
protected virtual ITenantStore TenantStore { get; }
|
||||
protected virtual ITenantResolveResultAccessor TenantResolveResultAccessor { get; }
|
||||
protected virtual IStringLocalizer<AbpMultiTenancyResource> StringLocalizer { get; }
|
||||
|
||||
public YiTenantConfigurationProvider(
|
||||
ITenantResolver tenantResolver,
|
||||
ITenantStore tenantStore,
|
||||
ITenantResolveResultAccessor tenantResolveResultAccessor,
|
||||
IStringLocalizer<AbpMultiTenancyResource> stringLocalizer)
|
||||
{
|
||||
TenantResolver = tenantResolver;
|
||||
TenantStore = tenantStore;
|
||||
TenantResolveResultAccessor = tenantResolveResultAccessor;
|
||||
StringLocalizer = stringLocalizer;
|
||||
}
|
||||
|
||||
public virtual async Task<TenantConfiguration?> GetAsync(bool saveResolveResult = false)
|
||||
{
|
||||
var resolveResult = await TenantResolver.ResolveTenantIdOrNameAsync();
|
||||
|
||||
if (saveResolveResult)
|
||||
{
|
||||
TenantResolveResultAccessor.Result = resolveResult;
|
||||
}
|
||||
|
||||
TenantConfiguration? tenant = null;
|
||||
if (resolveResult.TenantIdOrName != null)
|
||||
{
|
||||
tenant = await FindTenantAsync(resolveResult.TenantIdOrName);
|
||||
|
||||
if (tenant == null)
|
||||
{
|
||||
throw new BusinessException(
|
||||
code: "Volo.AbpIo.MultiTenancy:010001",
|
||||
message: StringLocalizer["TenantNotFoundMessage"],
|
||||
details: StringLocalizer["TenantNotFoundDetails", resolveResult.TenantIdOrName]
|
||||
);
|
||||
}
|
||||
|
||||
if (!tenant.IsActive)
|
||||
{
|
||||
throw new BusinessException(
|
||||
code: "Volo.AbpIo.MultiTenancy:010002",
|
||||
message: StringLocalizer["TenantNotActiveMessage"],
|
||||
details: StringLocalizer["TenantNotActiveDetails", resolveResult.TenantIdOrName]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return tenant;
|
||||
}
|
||||
|
||||
protected virtual async Task<TenantConfiguration?> FindTenantAsync(string tenantIdOrName)
|
||||
{
|
||||
if (Guid.TryParse(tenantIdOrName, out var parsedTenantId))
|
||||
{
|
||||
return await TenantStore.FindAsync(parsedTenantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return await TenantStore.FindAsync(tenantIdOrName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user