TenantCache.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. using Abp;
  2. using Abp.Domain.Repositories;
  3. using Abp.Domain.Uow;
  4. using Abp.Events.Bus.Entities;
  5. using Abp.Events.Bus.Handlers;
  6. using Abp.Runtime.Caching;
  7. using Abp.Runtime.Security;
  8. using VberZero.BaseSystem.MultiTenancy;
  9. namespace VberZero.MultiTenancy;
  10. public class TenantCache : ITenantCache, IEventHandler<EntityChangedEventData<Tenant>>
  11. {
  12. private readonly ICacheManager _cacheManager;
  13. private readonly IRepository<Tenant> _tenantRepository;
  14. private readonly IUnitOfWorkManager _unitOfWorkManager;
  15. public TenantCache(
  16. ICacheManager cacheManager,
  17. IRepository<Tenant> tenantRepository,
  18. IUnitOfWorkManager unitOfWorkManager)
  19. {
  20. _cacheManager = cacheManager;
  21. _tenantRepository = tenantRepository;
  22. _unitOfWorkManager = unitOfWorkManager;
  23. }
  24. public virtual TenantCacheItem Get(int tenantId)
  25. {
  26. var cacheItem = GetOrNull(tenantId);
  27. if (cacheItem == null)
  28. {
  29. throw new AbpException("There is no tenant with given id: " + tenantId);
  30. }
  31. return cacheItem;
  32. }
  33. public virtual TenantCacheItem Get(string tenancyName)
  34. {
  35. var cacheItem = GetOrNull(tenancyName);
  36. if (cacheItem == null)
  37. {
  38. throw new AbpException("There is no tenant with given tenancy name: " + tenancyName);
  39. }
  40. return cacheItem;
  41. }
  42. public virtual TenantCacheItem GetOrNull(string tenancyName)
  43. {
  44. var tenantId = _cacheManager
  45. .GetTenantByNameCache()
  46. .Get(
  47. tenancyName.ToLowerInvariant(),
  48. () => GetTenantOrNull(tenancyName).Id
  49. );
  50. if (tenantId == null)
  51. {
  52. return null;
  53. }
  54. return Get(tenantId.Value);
  55. }
  56. public TenantCacheItem GetOrNull(int tenantId)
  57. {
  58. return _cacheManager
  59. .GetTenantCache()!
  60. .Get(
  61. tenantId,
  62. () =>
  63. {
  64. var tenant = GetTenantOrNull(tenantId);
  65. if (tenant == null)
  66. {
  67. return null;
  68. }
  69. return CreateTenantCacheItem(tenant);
  70. }
  71. );
  72. }
  73. public virtual async Task<TenantCacheItem> GetAsync(int tenantId)
  74. {
  75. var cacheItem = await GetOrNullAsync(tenantId);
  76. if (cacheItem == null)
  77. {
  78. throw new AbpException("There is no tenant with given id: " + tenantId);
  79. }
  80. return cacheItem;
  81. }
  82. public virtual async Task<TenantCacheItem> GetAsync(string tenancyName)
  83. {
  84. var cacheItem = await GetOrNullAsync(tenancyName);
  85. if (cacheItem == null)
  86. {
  87. throw new AbpException("There is no tenant with given tenancy name: " + tenancyName);
  88. }
  89. return cacheItem;
  90. }
  91. public virtual async Task<TenantCacheItem> GetOrNullAsync(string tenancyName)
  92. {
  93. var tenantId = await _cacheManager
  94. .GetTenantByNameCache()
  95. .GetAsync(
  96. tenancyName.ToLowerInvariant(), async _ => (await GetTenantOrNullAsync(tenancyName)).Id
  97. );
  98. if (tenantId == null)
  99. {
  100. return null;
  101. }
  102. return await GetAsync(tenantId.Value);
  103. }
  104. public virtual async Task<TenantCacheItem> GetOrNullAsync(int tenantId)
  105. {
  106. return await _cacheManager
  107. .GetTenantCache()
  108. .GetAsync(
  109. tenantId, async _ =>
  110. {
  111. var tenant = await GetTenantOrNullAsync(tenantId);
  112. if (tenant == null)
  113. {
  114. return null;
  115. }
  116. return CreateTenantCacheItem(tenant);
  117. }
  118. );
  119. }
  120. protected virtual TenantCacheItem CreateTenantCacheItem(Tenant tenant)
  121. {
  122. return new TenantCacheItem
  123. {
  124. Id = tenant.Id,
  125. Name = tenant.Name,
  126. TenancyName = tenant.TenancyName,
  127. //EditionId = tenant.EditionId,
  128. ConnectionString = SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString),
  129. IsActive = tenant.IsActive
  130. };
  131. }
  132. protected virtual Tenant GetTenantOrNull(int tenantId)
  133. {
  134. return _unitOfWorkManager.WithUnitOfWork(() =>
  135. {
  136. using (_unitOfWorkManager.Current.SetTenantId(null))
  137. {
  138. return _tenantRepository.FirstOrDefault(tenantId);
  139. }
  140. });
  141. }
  142. protected virtual Tenant GetTenantOrNull(string tenancyName)
  143. {
  144. return _unitOfWorkManager.WithUnitOfWork(() =>
  145. {
  146. using (_unitOfWorkManager.Current.SetTenantId(null))
  147. {
  148. return _tenantRepository.FirstOrDefault(t => t.TenancyName == tenancyName);
  149. }
  150. });
  151. }
  152. protected virtual async Task<Tenant> GetTenantOrNullAsync(int tenantId)
  153. {
  154. return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
  155. {
  156. using (_unitOfWorkManager.Current.SetTenantId(null))
  157. {
  158. return await _tenantRepository.FirstOrDefaultAsync(tenantId);
  159. }
  160. });
  161. }
  162. protected virtual async Task<Tenant> GetTenantOrNullAsync(string tenancyName)
  163. {
  164. return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
  165. {
  166. using (_unitOfWorkManager.Current.SetTenantId(null))
  167. {
  168. return await _tenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName);
  169. }
  170. });
  171. }
  172. public virtual void HandleEvent(EntityChangedEventData<Tenant> eventData)
  173. {
  174. var existingCacheItem = _cacheManager.GetTenantCache().GetOrDefault(eventData.Entity.Id);
  175. _cacheManager
  176. .GetTenantByNameCache()
  177. .Remove(
  178. existingCacheItem != null
  179. ? existingCacheItem.TenancyName.ToLowerInvariant()
  180. : eventData.Entity.TenancyName.ToLowerInvariant()
  181. );
  182. _cacheManager
  183. .GetTenantCache()
  184. .Remove(eventData.Entity.Id);
  185. }
  186. }