TenantResolver.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using System;
  2. using System.Linq;
  3. using Abp.Configuration.Startup;
  4. using Abp.Dependency;
  5. using Abp.Runtime;
  6. using Castle.Core.Logging;
  7. namespace Abp.MultiTenancy
  8. {
  9. public class TenantResolver : ITenantResolver, ITransientDependency
  10. {
  11. private const string AmbientScopeContextKey = "Abp.MultiTenancy.TenantResolver.Resolving";
  12. public ILogger Logger { get; set; }
  13. private readonly IMultiTenancyConfig _multiTenancy;
  14. private readonly IIocResolver _iocResolver;
  15. private readonly ITenantStore _tenantStore;
  16. private readonly ITenantResolverCache _cache;
  17. private readonly IAmbientScopeProvider<bool> _ambientScopeProvider;
  18. public TenantResolver(
  19. IMultiTenancyConfig multiTenancy,
  20. IIocResolver iocResolver,
  21. ITenantStore tenantStore,
  22. ITenantResolverCache cache,
  23. IAmbientScopeProvider<bool> ambientScopeProvider)
  24. {
  25. _multiTenancy = multiTenancy;
  26. _iocResolver = iocResolver;
  27. _tenantStore = tenantStore;
  28. _cache = cache;
  29. _ambientScopeProvider = ambientScopeProvider;
  30. Logger = NullLogger.Instance;
  31. }
  32. public int? ResolveTenantId()
  33. {
  34. if (!_multiTenancy.Resolvers.Any())
  35. {
  36. return null;
  37. }
  38. if (_ambientScopeProvider.GetValue(AmbientScopeContextKey))
  39. {
  40. //Preventing recursive call of ResolveTenantId
  41. return null;
  42. }
  43. using (_ambientScopeProvider.BeginScope(AmbientScopeContextKey, true))
  44. {
  45. var cacheItem = _cache.Value;
  46. if (cacheItem != null)
  47. {
  48. return cacheItem.TenantId;
  49. }
  50. var tenantId = GetTenantIdFromContributors();
  51. _cache.Value = new TenantResolverCacheItem(tenantId);
  52. return tenantId;
  53. }
  54. }
  55. private int? GetTenantIdFromContributors()
  56. {
  57. foreach (var resolverType in _multiTenancy.Resolvers)
  58. {
  59. using (var resolver = _iocResolver.ResolveAsDisposable<ITenantResolveContributor>(resolverType))
  60. {
  61. int? tenantId;
  62. try
  63. {
  64. tenantId = resolver.Object.ResolveTenantId();
  65. }
  66. catch (Exception ex)
  67. {
  68. Logger.Warn(ex.ToString(), ex);
  69. continue;
  70. }
  71. if (tenantId == null)
  72. {
  73. continue;
  74. }
  75. if (_tenantStore.Find(tenantId.Value) == null)
  76. {
  77. continue;
  78. }
  79. return tenantId;
  80. }
  81. }
  82. return null;
  83. }
  84. }
  85. }