|  |  |  | @ -0,0 +1,116 @@ | 
			
		
	
		
			
				
					|  |  |  |  | using System; | 
			
		
	
		
			
				
					|  |  |  |  | using System.Threading.Tasks; | 
			
		
	
		
			
				
					|  |  |  |  | using Microsoft.AspNetCore.Http; | 
			
		
	
		
			
				
					|  |  |  |  | using Microsoft.Extensions.Caching.Distributed; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.AspNetCore.Mvc.MultiTenancy; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.Caching; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.DependencyInjection; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.Http.Client.DynamicProxying; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.MultiTenancy; | 
			
		
	
		
			
				
					|  |  |  |  | using Volo.Abp.Threading; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | namespace Volo.Abp.AspNetCore.Mvc.Client | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     public class RemoteTenantStore : ITenantStore, ITransientDependency | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         protected IHttpClientProxy<IAbpTenantAppService> Proxy { get; } | 
			
		
	
		
			
				
					|  |  |  |  |         protected IHttpContextAccessor HttpContextAccessor { get; } | 
			
		
	
		
			
				
					|  |  |  |  |         protected IDistributedCache<TenantConfiguration> Cache { get; } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public RemoteTenantStore( | 
			
		
	
		
			
				
					|  |  |  |  |             IHttpClientProxy<IAbpTenantAppService> proxy, | 
			
		
	
		
			
				
					|  |  |  |  |             IHttpContextAccessor httpContextAccessor, | 
			
		
	
		
			
				
					|  |  |  |  |             IDistributedCache<TenantConfiguration> cache) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             Proxy = proxy; | 
			
		
	
		
			
				
					|  |  |  |  |             HttpContextAccessor = httpContextAccessor; | 
			
		
	
		
			
				
					|  |  |  |  |             Cache = cache; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public async Task<TenantConfiguration> FindAsync(string name) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             var cacheKey = CreateCacheKey(name); | 
			
		
	
		
			
				
					|  |  |  |  |             var httpContext = HttpContextAccessor?.HttpContext; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |                 return tenantConfiguration; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             tenantConfiguration = await Cache.GetOrAddAsync( | 
			
		
	
		
			
				
					|  |  |  |  |                 cacheKey, | 
			
		
	
		
			
				
					|  |  |  |  |                 async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name)), | 
			
		
	
		
			
				
					|  |  |  |  |                 () => new DistributedCacheEntryOptions | 
			
		
	
		
			
				
					|  |  |  |  |                 { | 
			
		
	
		
			
				
					|  |  |  |  |                     AbsoluteExpirationRelativeToNow = | 
			
		
	
		
			
				
					|  |  |  |  |                         TimeSpan.FromMinutes(5) //TODO: Should be configurable. | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (httpContext != null) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |                 httpContext.Items[cacheKey] = tenantConfiguration; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             return tenantConfiguration; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public async Task<TenantConfiguration> FindAsync(Guid id) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             var cacheKey = CreateCacheKey(id); | 
			
		
	
		
			
				
					|  |  |  |  |             var httpContext = HttpContextAccessor?.HttpContext; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (httpContext != null && httpContext.Items[cacheKey] is TenantConfiguration tenantConfiguration) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |                 return tenantConfiguration; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             tenantConfiguration = await Cache.GetOrAddAsync( | 
			
		
	
		
			
				
					|  |  |  |  |                 cacheKey, | 
			
		
	
		
			
				
					|  |  |  |  |                 async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id)), | 
			
		
	
		
			
				
					|  |  |  |  |                 () => new DistributedCacheEntryOptions | 
			
		
	
		
			
				
					|  |  |  |  |                 { | 
			
		
	
		
			
				
					|  |  |  |  |                     AbsoluteExpirationRelativeToNow = | 
			
		
	
		
			
				
					|  |  |  |  |                         TimeSpan.FromMinutes(5) //TODO: Should be configurable. | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             ); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             if (httpContext != null) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |                 httpContext.Items[cacheKey] = tenantConfiguration; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             return tenantConfiguration; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public TenantConfiguration Find(string name) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             return AsyncHelper.RunSync(() => FindAsync(name)); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public TenantConfiguration Find(Guid id) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             return AsyncHelper.RunSync(() => FindAsync(id)); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         protected virtual TenantConfiguration CreateTenantConfiguration(FindTenantResultDto tenantResultDto) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             if (!tenantResultDto.Success || tenantResultDto.TenantId == null) | 
			
		
	
		
			
				
					|  |  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |  |                 return null; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             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}"; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } |