From bf44f640929144cadf4dbacfaf77de0d01c7f1e0 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 8 Dec 2023 11:58:15 +0800 Subject: [PATCH 1/4] Clear the tenant cache when creating/update/deleting. --- .../Mvc/Client/MvcRemoteTenantStore.cs | 18 ++++-------------- .../TenantConfigurationCacheHelper.cs | 16 ++++++++++++++++ ...nantManagement.Application.Contracts.csproj | 1 + ...nantManagementApplicationContractsModule.cs | 4 +++- .../Abp/TenantManagement/TenantAppService.cs | 16 +++++++++++++++- 5 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs index aa9fc4beb8c..8e163bdd1f8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs @@ -33,7 +33,7 @@ public MvcRemoteTenantStore( public async Task FindAsync(string name) { - var cacheKey = CreateCacheKey(name); + var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(name); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) @@ -60,7 +60,7 @@ public MvcRemoteTenantStore( public async Task FindAsync(Guid id) { - var cacheKey = CreateCacheKey(id); + var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(id); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) @@ -87,7 +87,7 @@ public MvcRemoteTenantStore( public TenantConfiguration Find(string name) { - var cacheKey = CreateCacheKey(name); + var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(name); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) @@ -114,7 +114,7 @@ public TenantConfiguration Find(string name) public TenantConfiguration Find(Guid id) { - var cacheKey = CreateCacheKey(id); + var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(id); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) @@ -148,14 +148,4 @@ public TenantConfiguration Find(Guid id) return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name!); } - - protected virtual string CreateCacheKey(string tenantName) - { - return $"RemoteTenantStore_Name_{tenantName}"; - } - - protected virtual string CreateCacheKey(Guid tenantId) - { - return $"RemoteTenantStore_Id_{tenantId:N}"; - } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs new file mode 100644 index 00000000000..666cda31c0f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.MultiTenancy; + +public static class TenantConfigurationCacheHelper +{ + public static string CreateCacheKey(string tenantName) + { + return $"RemoteTenantStore_Name_{tenantName}"; + } + + public static string CreateCacheKey(Guid tenantId) + { + return $"RemoteTenantStore_Id_{tenantId:N}"; + } +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj index 8e849785b7d..58009adef18 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj @@ -18,6 +18,7 @@ + diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs index 27bfeaaa367..dddb67ac834 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs @@ -1,4 +1,5 @@ using Volo.Abp.Application; +using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Authorization; using Volo.Abp.Modularity; using Volo.Abp.ObjectExtending; @@ -10,7 +11,8 @@ namespace Volo.Abp.TenantManagement; [DependsOn( typeof(AbpDddApplicationContractsModule), typeof(AbpTenantManagementDomainSharedModule), - typeof(AbpAuthorizationAbstractionsModule) + typeof(AbpAuthorizationAbstractionsModule), + typeof(AbpAspNetCoreMvcContractsModule) )] public class AbpTenantManagementApplicationContractsModule : AbpModule { diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs index 46c85578f44..cc9ce7455df 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc.MultiTenancy; +using Volo.Abp.Caching; using Volo.Abp.Data; using Volo.Abp.EventBus.Distributed; using Volo.Abp.MultiTenancy; @@ -17,17 +19,20 @@ public class TenantAppService : TenantManagementAppServiceBase, ITenantAppServic protected ITenantRepository TenantRepository { get; } protected ITenantManager TenantManager { get; } protected IDistributedEventBus DistributedEventBus { get; } + protected IDistributedCache TenantConfigurationCache { get; } public TenantAppService( ITenantRepository tenantRepository, ITenantManager tenantManager, IDataSeeder dataSeeder, - IDistributedEventBus distributedEventBus) + IDistributedEventBus distributedEventBus, + IDistributedCache tenantConfigurationCache) { DataSeeder = dataSeeder; TenantRepository = tenantRepository; TenantManager = tenantManager; DistributedEventBus = distributedEventBus; + TenantConfigurationCache = tenantConfigurationCache; } public virtual async Task GetAsync(Guid id) @@ -91,6 +96,9 @@ await DataSeeder.SeedAsync( ); } + await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Id)); + await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Name)); + return ObjectMapper.Map(tenant); } @@ -106,6 +114,9 @@ public virtual async Task UpdateAsync(Guid id, TenantUpdateDto input) await TenantRepository.UpdateAsync(tenant); + await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Id)); + await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Name)); + return ObjectMapper.Map(tenant); } @@ -119,6 +130,9 @@ public virtual async Task DeleteAsync(Guid id) } await TenantRepository.DeleteAsync(tenant); + + await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Id)); + await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Name)); } [Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)] From 714b59a0598690a7d01a7d88dfab400ebd61206e Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 8 Dec 2023 14:17:19 +0800 Subject: [PATCH 2/4] Remove `TenantCacheItem` and use `TenantConfigurationCacheItem`. --- .../AbpAspNetCoreMvcClientCacheOptions.cs | 3 - .../Client/AbpAspNetCoreMvcClientModule.cs | 1 - .../Mvc/Client/MvcRemoteTenantStore.cs | 108 +++++++----------- .../TenantConfigurationCacheHelper.cs | 16 --- .../TenantConfigurationCacheItem.cs | 43 +++++++ ...antManagement.Application.Contracts.csproj | 1 - ...antManagementApplicationContractsModule.cs | 4 +- .../Abp/TenantManagement/TenantAppService.cs | 26 +++-- .../Abp/TenantManagement/TenantCacheItem.cs | 35 ------ .../TenantCacheItemInvalidator.cs | 23 ---- .../Volo/Abp/TenantManagement/TenantStore.cs | 18 +-- .../TenantCacheItemInvalidator_Tests.cs | 40 +++---- 12 files changed, 132 insertions(+), 186 deletions(-) delete mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs create mode 100644 framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfigurationCacheItem.cs delete mode 100644 modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItem.cs delete mode 100644 modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItemInvalidator.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs index c27670246ed..473615af5ea 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientCacheOptions.cs @@ -4,13 +4,10 @@ namespace Volo.Abp.AspNetCore.Mvc.Client; public class AbpAspNetCoreMvcClientCacheOptions { - public TimeSpan TenantConfigurationCacheAbsoluteExpiration { get; set; } - public TimeSpan ApplicationConfigurationDtoCacheAbsoluteExpiration { get; set; } public AbpAspNetCoreMvcClientCacheOptions() { - TenantConfigurationCacheAbsoluteExpiration = TimeSpan.FromMinutes(5); ApplicationConfigurationDtoCacheAbsoluteExpiration = TimeSpan.FromSeconds(300); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs index 610a41eefda..a22e68b7b94 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/AbpAspNetCoreMvcClientModule.cs @@ -18,7 +18,6 @@ public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => { - options.TenantConfigurationCacheAbsoluteExpiration = TimeSpan.FromSeconds(5); options.ApplicationConfigurationDtoCacheAbsoluteExpiration = TimeSpan.FromSeconds(5); }); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs index 8e163bdd1f8..e0c450b8b40 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs @@ -1,10 +1,8 @@ using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Options; using Pages.Abp.MultiTenancy.ClientProxies; -using Volo.Abp.AspNetCore.Mvc.MultiTenancy; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; @@ -16,13 +14,13 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency { protected AbpTenantClientProxy TenantAppService { get; } protected IHttpContextAccessor HttpContextAccessor { get; } - protected IDistributedCache Cache { get; } + protected IDistributedCache Cache { get; } protected AbpAspNetCoreMvcClientCacheOptions Options { get; } public MvcRemoteTenantStore( AbpTenantClientProxy tenantAppService, IHttpContextAccessor httpContextAccessor, - IDistributedCache cache, + IDistributedCache cache, IOptions options) { TenantAppService = tenantAppService; @@ -33,119 +31,101 @@ public MvcRemoteTenantStore( public async Task FindAsync(string name) { - var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(name); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name); var httpContext = HttpContextAccessor?.HttpContext; - if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) + if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) { - return tenantConfiguration; + return tenantConfigurationInHttpContext?.Value; } - tenantConfiguration = (await Cache.GetOrAddAsync( - cacheKey, - async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))!, - () => new DistributedCacheEntryOptions - { - AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration - } - ))!; + var tenantConfiguration = await Cache.GetAsync(cacheKey); + if (tenantConfiguration == null) + { + await TenantAppService.FindTenantByNameAsync(name); + tenantConfiguration = await Cache.GetAsync(cacheKey); + } if (httpContext != null) { httpContext.Items[cacheKey] = tenantConfiguration; } - return tenantConfiguration; + return tenantConfiguration?.Value; } public async Task FindAsync(Guid id) { - var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(id); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(id); var httpContext = HttpContextAccessor?.HttpContext; - if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) + if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) { - return tenantConfiguration; + return tenantConfigurationInHttpContext?.Value; } - tenantConfiguration = (await Cache.GetOrAddAsync( - cacheKey, - async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id))!, - () => new DistributedCacheEntryOptions - { - AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration - } - ))!; + var tenantConfiguration = await Cache.GetAsync(cacheKey); + if (tenantConfiguration == null) + { + await TenantAppService.FindTenantByIdAsync(id); + tenantConfiguration = await Cache.GetAsync(cacheKey); + } if (httpContext != null) { httpContext.Items[cacheKey] = tenantConfiguration; } - return tenantConfiguration; + return tenantConfiguration?.Value; } - public TenantConfiguration Find(string name) + public TenantConfiguration? Find(string name) { - var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(name); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name); var httpContext = HttpContextAccessor?.HttpContext; - if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) + if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) { - return tenantConfiguration; + return tenantConfigurationInHttpContext?.Value; } - tenantConfiguration = Cache.GetOrAdd( - cacheKey, - () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))!), - () => new DistributedCacheEntryOptions - { - AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration - } - )!; + var tenantConfiguration = Cache.Get(cacheKey); + if (tenantConfiguration == null) + { + AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(name)); + tenantConfiguration = Cache.Get(cacheKey); + } if (httpContext != null) { httpContext.Items[cacheKey] = tenantConfiguration; } - return tenantConfiguration; + return tenantConfiguration?.Value; } - public TenantConfiguration Find(Guid id) + public TenantConfiguration? Find(Guid id) { - var cacheKey = TenantConfigurationCacheHelper.CreateCacheKey(id); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(id); var httpContext = HttpContextAccessor?.HttpContext; - if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) + if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) { - return tenantConfiguration; + return tenantConfigurationInHttpContext?.Value; } - tenantConfiguration = Cache.GetOrAdd( - cacheKey, - () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByIdAsync(id))!), - () => new DistributedCacheEntryOptions - { - AbsoluteExpirationRelativeToNow = Options.TenantConfigurationCacheAbsoluteExpiration - } - )!; - - if (httpContext != null) + var tenantConfiguration = Cache.Get(cacheKey); + if (tenantConfiguration == null) { - httpContext.Items[cacheKey] = tenantConfiguration; + AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByIdAsync(id)); + tenantConfiguration = Cache.Get(cacheKey); } - return tenantConfiguration; - } - - protected virtual TenantConfiguration? CreateTenantConfiguration(FindTenantResultDto tenantResultDto) - { - if (!tenantResultDto.Success || tenantResultDto.TenantId == null) + if (httpContext != null) { - return null; + httpContext.Items[cacheKey] = tenantConfiguration; } - return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name!); + return tenantConfiguration?.Value; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs deleted file mode 100644 index 666cda31c0f..00000000000 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/TenantConfigurationCacheHelper.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Volo.Abp.AspNetCore.Mvc.MultiTenancy; - -public static class TenantConfigurationCacheHelper -{ - public static string CreateCacheKey(string tenantName) - { - return $"RemoteTenantStore_Name_{tenantName}"; - } - - public static string CreateCacheKey(Guid tenantId) - { - return $"RemoteTenantStore_Id_{tenantId:N}"; - } -} diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfigurationCacheItem.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfigurationCacheItem.cs new file mode 100644 index 00000000000..526f60d8c01 --- /dev/null +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfigurationCacheItem.cs @@ -0,0 +1,43 @@ +using System; + +namespace Volo.Abp.MultiTenancy; + +[Serializable] +[IgnoreMultiTenancy] +public class TenantConfigurationCacheItem +{ + private const string CacheKeyFormat = "i:{0},n:{1}"; + + public TenantConfiguration? Value { get; set; } + + public TenantConfigurationCacheItem() + { + + } + + public TenantConfigurationCacheItem(TenantConfiguration? value) + { + Value = value; + } + + public static string CalculateCacheKey(Guid? id, string? name) + { + if (id == null && name.IsNullOrWhiteSpace()) + { + throw new AbpException("Both id and name can't be invalid."); + } + return string.Format(CacheKeyFormat, + id?.ToString() ?? "null", + (name.IsNullOrWhiteSpace() ? "null" : name)); + } + + public static string CalculateCacheKey(Guid id) + { + return string.Format(CacheKeyFormat, id.ToString(), "null" ); + } + + public static string CalculateCacheKey(string name) + { + return string.Format(CacheKeyFormat, "null", name); + } +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj index 58009adef18..8e849785b7d 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo.Abp.TenantManagement.Application.Contracts.csproj @@ -18,7 +18,6 @@ - diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs index dddb67ac834..27bfeaaa367 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/AbpTenantManagementApplicationContractsModule.cs @@ -1,5 +1,4 @@ using Volo.Abp.Application; -using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Authorization; using Volo.Abp.Modularity; using Volo.Abp.ObjectExtending; @@ -11,8 +10,7 @@ namespace Volo.Abp.TenantManagement; [DependsOn( typeof(AbpDddApplicationContractsModule), typeof(AbpTenantManagementDomainSharedModule), - typeof(AbpAuthorizationAbstractionsModule), - typeof(AbpAspNetCoreMvcContractsModule) + typeof(AbpAuthorizationAbstractionsModule) )] public class AbpTenantManagementApplicationContractsModule : AbpModule { diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs index cc9ce7455df..060e5032350 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; -using Volo.Abp.AspNetCore.Mvc.MultiTenancy; using Volo.Abp.Caching; using Volo.Abp.Data; using Volo.Abp.EventBus.Distributed; @@ -19,14 +18,14 @@ public class TenantAppService : TenantManagementAppServiceBase, ITenantAppServic protected ITenantRepository TenantRepository { get; } protected ITenantManager TenantManager { get; } protected IDistributedEventBus DistributedEventBus { get; } - protected IDistributedCache TenantConfigurationCache { get; } + protected IDistributedCache TenantConfigurationCache { get; } public TenantAppService( ITenantRepository tenantRepository, ITenantManager tenantManager, IDataSeeder dataSeeder, IDistributedEventBus distributedEventBus, - IDistributedCache tenantConfigurationCache) + IDistributedCache tenantConfigurationCache) { DataSeeder = dataSeeder; TenantRepository = tenantRepository; @@ -96,9 +95,6 @@ await DataSeeder.SeedAsync( ); } - await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Id)); - await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Name)); - return ObjectMapper.Map(tenant); } @@ -107,6 +103,13 @@ public virtual async Task UpdateAsync(Guid id, TenantUpdateDto input) { var tenant = await TenantRepository.GetAsync(id); + await TenantConfigurationCache.RemoveManyAsync( + new[] + { + TenantConfigurationCacheItem.CalculateCacheKey(tenant.Id, null), + TenantConfigurationCacheItem.CalculateCacheKey(null, tenant.Name), + }); + await TenantManager.ChangeNameAsync(tenant, input.Name); tenant.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); @@ -114,9 +117,6 @@ public virtual async Task UpdateAsync(Guid id, TenantUpdateDto input) await TenantRepository.UpdateAsync(tenant); - await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Id)); - await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Name)); - return ObjectMapper.Map(tenant); } @@ -131,8 +131,12 @@ public virtual async Task DeleteAsync(Guid id) await TenantRepository.DeleteAsync(tenant); - await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Id)); - await TenantConfigurationCache.RemoveAsync(TenantConfigurationCacheHelper.CreateCacheKey(tenant.Name)); + await TenantConfigurationCache.RemoveManyAsync( + new[] + { + TenantConfigurationCacheItem.CalculateCacheKey(tenant.Id, null), + TenantConfigurationCacheItem.CalculateCacheKey(null, tenant.Name), + }); } [Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)] diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItem.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItem.cs deleted file mode 100644 index ee17d7196de..00000000000 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItem.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using Volo.Abp.MultiTenancy; - -namespace Volo.Abp.TenantManagement; - -[Serializable] -[IgnoreMultiTenancy] -public class TenantCacheItem -{ - private const string CacheKeyFormat = "i:{0},n:{1}"; - - public TenantConfiguration Value { get; set; } - - public TenantCacheItem() - { - - } - - public TenantCacheItem(TenantConfiguration value) - { - Value = value; - } - - public static string CalculateCacheKey(Guid? id, string name) - { - if (id == null && name.IsNullOrWhiteSpace()) - { - throw new AbpException("Both id and name can't be invalid."); - } - - return string.Format(CacheKeyFormat, - id?.ToString() ?? "null", - (name.IsNullOrWhiteSpace() ? "null" : name)); - } -} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItemInvalidator.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItemInvalidator.cs deleted file mode 100644 index 8bbb8bd49cc..00000000000 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantCacheItemInvalidator.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.Caching; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Entities.Events; -using Volo.Abp.EventBus; - -namespace Volo.Abp.TenantManagement; - -public class TenantCacheItemInvalidator : ILocalEventHandler>, ITransientDependency -{ - protected IDistributedCache Cache { get; } - - public TenantCacheItemInvalidator(IDistributedCache cache) - { - Cache = cache; - } - - public virtual async Task HandleEventAsync(EntityChangedEventData eventData) - { - await Cache.RemoveAsync(TenantCacheItem.CalculateCacheKey(eventData.Entity.Id, null), considerUow: true); - await Cache.RemoveAsync(TenantCacheItem.CalculateCacheKey(null, eventData.Entity.Name), considerUow: true); - } -} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs index 262e464a453..5fd23add6bb 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs @@ -13,13 +13,13 @@ public class TenantStore : ITenantStore, ITransientDependency protected ITenantRepository TenantRepository { get; } protected IObjectMapper ObjectMapper { get; } protected ICurrentTenant CurrentTenant { get; } - protected IDistributedCache Cache { get; } + protected IDistributedCache Cache { get; } public TenantStore( ITenantRepository tenantRepository, IObjectMapper objectMapper, ICurrentTenant currentTenant, - IDistributedCache cache) + IDistributedCache cache) { TenantRepository = tenantRepository; ObjectMapper = objectMapper; @@ -49,7 +49,7 @@ public virtual TenantConfiguration Find(Guid id) return (GetCacheItem(id, null)).Value; } - protected virtual async Task GetCacheItemAsync(Guid? id, string name) + protected virtual async Task GetCacheItemAsync(Guid? id, string name) { var cacheKey = CalculateCacheKey(id, name); @@ -80,16 +80,16 @@ protected virtual async Task GetCacheItemAsync(Guid? id, string throw new AbpException("Both id and name can't be invalid."); } - protected virtual async Task SetCacheAsync(string cacheKey, [CanBeNull] Tenant tenant) + protected virtual async Task SetCacheAsync(string cacheKey, [CanBeNull] Tenant tenant) { var tenantConfiguration = tenant != null ? ObjectMapper.Map(tenant) : null; - var cacheItem = new TenantCacheItem(tenantConfiguration); + var cacheItem = new TenantConfigurationCacheItem(tenantConfiguration); await Cache.SetAsync(cacheKey, cacheItem, considerUow: true); return cacheItem; } [Obsolete("Use GetCacheItemAsync method.")] - protected virtual TenantCacheItem GetCacheItem(Guid? id, string name) + protected virtual TenantConfigurationCacheItem GetCacheItem(Guid? id, string name) { var cacheKey = CalculateCacheKey(id, name); @@ -121,16 +121,16 @@ protected virtual TenantCacheItem GetCacheItem(Guid? id, string name) } [Obsolete("Use SetCacheAsync method.")] - protected virtual TenantCacheItem SetCache(string cacheKey, [CanBeNull] Tenant tenant) + protected virtual TenantConfigurationCacheItem SetCache(string cacheKey, [CanBeNull] Tenant tenant) { var tenantConfiguration = tenant != null ? ObjectMapper.Map(tenant) : null; - var cacheItem = new TenantCacheItem(tenantConfiguration); + var cacheItem = new TenantConfigurationCacheItem(tenantConfiguration); Cache.Set(cacheKey, cacheItem, considerUow: true); return cacheItem; } protected virtual string CalculateCacheKey(Guid? id, string name) { - return TenantCacheItem.CalculateCacheKey(id, name); + return TenantConfigurationCacheItem.CalculateCacheKey(id, name); } } diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs index ad4e66aa7ac..85416c77551 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs @@ -6,15 +6,15 @@ namespace Volo.Abp.TenantManagement; -public class TenantCacheItemInvalidator_Tests : AbpTenantManagementDomainTestBase +public class TenantConfigurationCacheItemInvalidator_Tests : AbpTenantManagementDomainTestBase { - private readonly IDistributedCache _cache; + private readonly IDistributedCache _cache; private readonly ITenantStore _tenantStore; private readonly ITenantRepository _tenantRepository; - public TenantCacheItemInvalidator_Tests() + public TenantConfigurationCacheItemInvalidator_Tests() { - _cache = GetRequiredService>(); + _cache = GetRequiredService>(); _tenantStore = GetRequiredService(); _tenantRepository = GetRequiredService(); } @@ -25,27 +25,27 @@ public async Task Get_Tenant_Should_Cached() var acme = await _tenantRepository.FindByNameAsync("acme"); acme.ShouldNotBeNull(); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); await _tenantStore.FindAsync(acme.Id); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); await _tenantStore.FindAsync(acme.Name); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); var volosoft = _tenantRepository.FindByName("volosoft"); volosoft.ShouldNotBeNull(); - (_cache.Get(TenantCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); - (_cache.Get(TenantCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); _tenantStore.Find(volosoft.Id); - (_cache.Get(TenantCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); _tenantStore.Find(volosoft.Name); - (_cache.Get(TenantCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); } [Fact] @@ -58,13 +58,13 @@ public async Task Cache_Should_Invalidator_When_Tenant_Changed() await _tenantStore.FindAsync(acme.Id); await _tenantStore.FindAsync(acme.Name); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); await _tenantRepository.DeleteAsync(acme); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); var volosoft = await _tenantRepository.FindByNameAsync("volosoft"); @@ -74,12 +74,12 @@ public async Task Cache_Should_Invalidator_When_Tenant_Changed() _tenantStore.Find(volosoft.Id); _tenantStore.Find(volosoft.Name); - (_cache.Get(TenantCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); - (_cache.Get(TenantCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); await _tenantRepository.DeleteAsync(volosoft); - (_cache.Get(TenantCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); - (_cache.Get(TenantCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); } } From 037147ed47588e72f82b0815fa68f0386579dcea Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 8 Dec 2023 14:44:53 +0800 Subject: [PATCH 3/4] Add `TenantConfigurationCacheItemInvalidator`. --- .../Abp/TenantManagement/TenantAppService.cs | 20 +-------- ...TenantConfigurationCacheItemInvalidator.cs | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs index 060e5032350..46c85578f44 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application/Volo/Abp/TenantManagement/TenantAppService.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; -using Volo.Abp.Caching; using Volo.Abp.Data; using Volo.Abp.EventBus.Distributed; using Volo.Abp.MultiTenancy; @@ -18,20 +17,17 @@ public class TenantAppService : TenantManagementAppServiceBase, ITenantAppServic protected ITenantRepository TenantRepository { get; } protected ITenantManager TenantManager { get; } protected IDistributedEventBus DistributedEventBus { get; } - protected IDistributedCache TenantConfigurationCache { get; } public TenantAppService( ITenantRepository tenantRepository, ITenantManager tenantManager, IDataSeeder dataSeeder, - IDistributedEventBus distributedEventBus, - IDistributedCache tenantConfigurationCache) + IDistributedEventBus distributedEventBus) { DataSeeder = dataSeeder; TenantRepository = tenantRepository; TenantManager = tenantManager; DistributedEventBus = distributedEventBus; - TenantConfigurationCache = tenantConfigurationCache; } public virtual async Task GetAsync(Guid id) @@ -103,13 +99,6 @@ public virtual async Task UpdateAsync(Guid id, TenantUpdateDto input) { var tenant = await TenantRepository.GetAsync(id); - await TenantConfigurationCache.RemoveManyAsync( - new[] - { - TenantConfigurationCacheItem.CalculateCacheKey(tenant.Id, null), - TenantConfigurationCacheItem.CalculateCacheKey(null, tenant.Name), - }); - await TenantManager.ChangeNameAsync(tenant, input.Name); tenant.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); @@ -130,13 +119,6 @@ public virtual async Task DeleteAsync(Guid id) } await TenantRepository.DeleteAsync(tenant); - - await TenantConfigurationCache.RemoveManyAsync( - new[] - { - TenantConfigurationCacheItem.CalculateCacheKey(tenant.Id, null), - TenantConfigurationCacheItem.CalculateCacheKey(null, tenant.Name), - }); } [Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)] diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs new file mode 100644 index 00000000000..e629186e20d --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events; +using Volo.Abp.EventBus; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.TenantManagement; + + +public class TenantConfigurationCacheItemInvalidator : + ILocalEventHandler>, + ILocalEventHandler>, ITransientDependency +{ + protected IDistributedCache Cache { get; } + + public TenantConfigurationCacheItemInvalidator(IDistributedCache cache) + { + Cache = cache; + } + + public virtual async Task HandleEventAsync(EntityChangedEventData eventData) + { + await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.Name); + } + + public virtual async Task HandleEventAsync(EntityDeletedEventData eventData) + { + await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.Name); + } + + protected virtual async Task ClearCacheAsync(Guid? id, string name) + { + await Cache.RemoveManyAsync( + new[] + { + TenantConfigurationCacheItem.CalculateCacheKey(id, null), + TenantConfigurationCacheItem.CalculateCacheKey(null, name), + }); + } +} From 58f31c88a06e062a1eda1ffd46047ffd3c70308c Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 8 Dec 2023 15:53:03 +0800 Subject: [PATCH 4/4] Clear tenant cache on name change. --- .../Abp/TenantManagement/TenantManager.cs | 9 +++++++-- .../TenantCacheItemInvalidator_Tests.cs | 19 +++++++++++++++++++ .../AbpTenantManagementTestDataBuilder.cs | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs index fa388426d9b..1ad7324c359 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs @@ -1,17 +1,21 @@ using System; using System.Threading.Tasks; +using Volo.Abp.Caching; using Volo.Abp.Domain.Services; +using Volo.Abp.MultiTenancy; namespace Volo.Abp.TenantManagement; public class TenantManager : DomainService, ITenantManager { protected ITenantRepository TenantRepository { get; } + protected IDistributedCache Cache { get; } - public TenantManager(ITenantRepository tenantRepository) + public TenantManager(ITenantRepository tenantRepository, + IDistributedCache cache) { TenantRepository = tenantRepository; - + Cache = cache; } public virtual async Task CreateAsync(string name) @@ -28,6 +32,7 @@ public virtual async Task ChangeNameAsync(Tenant tenant, string name) Check.NotNull(name, nameof(name)); await ValidateNameAsync(name, tenant.Id); + await Cache.RemoveAsync(TenantConfigurationCacheItem.CalculateCacheKey(tenant.Name)); tenant.SetName(name); } diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs index 85416c77551..96714025600 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs @@ -11,12 +11,14 @@ public class TenantConfigurationCacheItemInvalidator_Tests : AbpTenantManagement private readonly IDistributedCache _cache; private readonly ITenantStore _tenantStore; private readonly ITenantRepository _tenantRepository; + private readonly ITenantManager _tenantManager; public TenantConfigurationCacheItemInvalidator_Tests() { _cache = GetRequiredService>(); _tenantStore = GetRequiredService(); _tenantRepository = GetRequiredService(); + _tenantManager = GetRequiredService(); } [Fact] @@ -81,5 +83,22 @@ public async Task Cache_Should_Invalidator_When_Tenant_Changed() (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); + + var abp = await _tenantRepository.FindByNameAsync("abp"); + abp.ShouldNotBeNull(); + + // Find will cache tenant. + await _tenantStore.FindAsync(abp.Id); + await _tenantStore.FindAsync(abp.Name); + + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(abp.Id, null))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, abp.Name))).ShouldNotBeNull(); + + await _tenantManager.ChangeNameAsync(abp, "abp2"); + await _tenantRepository.UpdateAsync(abp); + + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(abp.Id, null))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, "abp"))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, "abp2"))).ShouldBeNull(); } } diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/AbpTenantManagementTestDataBuilder.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/AbpTenantManagementTestDataBuilder.cs index 26abc1cd97c..2a4b55ee271 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/AbpTenantManagementTestDataBuilder.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/AbpTenantManagementTestDataBuilder.cs @@ -32,5 +32,8 @@ private async Task AddTenantsAsync() var volosoft = await _tenantManager.CreateAsync("volosoft"); await _tenantRepository.InsertAsync(volosoft); + + var abp = await _tenantManager.CreateAsync("abp"); + await _tenantRepository.InsertAsync(abp); } }