SqlSugarAndConfigurationTenantStore.cs
4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System.Xml.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.Data;
using Volo.Abp.MultiTenancy;
using Volo.Abp.MultiTenancy.ConfigurationStore;
using Volo.Abp.Uow;
namespace Yi.Framework.TenantManagement.Domain
{
public class SqlSugarAndConfigurationTenantStore : DefaultTenantStore, ITenantStore
{
private ISqlSugarTenantRepository TenantRepository { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IDistributedCache<TenantCacheItem> Cache { get; }
private IUnitOfWorkManager _unitOfWorkManager;
public SqlSugarAndConfigurationTenantStore(ISqlSugarTenantRepository repository,
IDistributedCache<TenantCacheItem> cache,
ICurrentTenant currentTenant,
IOptionsMonitor<AbpDefaultTenantStoreOptions> options, IUnitOfWorkManager unitOfWorkManager) : base(options)
{
TenantRepository = repository;
Cache = cache;
CurrentTenant = currentTenant;
_unitOfWorkManager = unitOfWorkManager;
}
public new TenantConfiguration? Find(string name)
{
throw new NotImplementedException("请使用异步方法");
}
public new TenantConfiguration? Find(Guid id)
{
throw new NotImplementedException("请使用异步方法");
}
public new async Task<TenantConfiguration?> FindAsync(string name)
{
var tenantFromOptions = await base.FindAsync(name);
//如果配置文件不存在改租户
if (tenantFromOptions is null)
{
return (await GetCacheItemAsync(null, name)).Value;
}
else
{
return tenantFromOptions;
}
}
public new async Task<TenantConfiguration?> FindAsync(Guid id)
{
var tenantFromOptions = await base.FindAsync(id);
if (tenantFromOptions is null)
{
return (await GetCacheItemAsync(id, null)).Value;
}
else
{
return tenantFromOptions;
}
}
protected virtual async Task<TenantCacheItem> GetCacheItemAsync(Guid? id, string name)
{
var cacheKey = CalculateCacheKey(id, name);
var cacheItem = await Cache.GetAsync(cacheKey, considerUow: true);
if (cacheItem != null)
{
return cacheItem;
}
if (id.HasValue)
{
using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
TenantAggregateRoot tenant = null;
using (var uow=_unitOfWorkManager.Begin(isTransactional:false))
{
tenant = await TenantRepository.FindAsync(id.Value);
await uow.CompleteAsync();
}
return await SetCacheAsync(cacheKey, tenant);
}
}
if (!name.IsNullOrWhiteSpace())
{
using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities!
{
var tenant = await TenantRepository.FindByNameAsync(name);
return await SetCacheAsync(cacheKey, tenant);
}
}
throw new AbpException("Both id and name can't be invalid.");
}
protected virtual async Task<TenantCacheItem> SetCacheAsync(string cacheKey, [CanBeNull] TenantAggregateRoot tenant)
{
var tenantConfiguration = tenant != null ? MapToConfiguration(tenant) : null;
var cacheItem = new TenantCacheItem(tenantConfiguration);
await Cache.SetAsync(cacheKey, cacheItem, considerUow: true);
return cacheItem;
}
private TenantConfiguration MapToConfiguration(TenantAggregateRoot tenantAggregateRoot)
{
var tenantConfiguration = new TenantConfiguration();
tenantConfiguration.Id = tenantAggregateRoot.Id;
tenantConfiguration.Name = tenantAggregateRoot.Name;
tenantConfiguration.ConnectionStrings = MaptoString(tenantAggregateRoot.TenantConnectionString);
tenantConfiguration.IsActive = true;
return tenantConfiguration;
}
private ConnectionStrings? MaptoString(string tenantConnectionString)
{
var connectionStrings = new ConnectionStrings();
connectionStrings[ConnectionStrings.DefaultConnectionStringName] = tenantConnectionString;
return connectionStrings;
}
protected virtual string CalculateCacheKey(Guid? id, string name)
{
return TenantCacheItem.CalculateCacheKey(id, name);
}
}
}