ner container)
{
ConigureSqlserver(container);
}
private void ConigureSqlserver(Container container)
{
var dbFactory = new OrmLiteConnectionFactory(
"Data Source=.; Initial Catalog=TMaster;User Id=TMaster;Password=t123;pooling=true;", SqlServerDialect.Provider);
const int noOfTennants = 3;
container.Register<IDbConnectionFactory>(c =>new MultiTenantDbFactory(dbFactory));
var multiDbFactory = (MultiTenantDbFactory)container.Resolve<IDbConnectionFactory>();
using (var db = multiDbFactory.OpenTenant())
InitDb(db, "TMaster", "Masters inc.");
for(int i=1; i<= noOfTennants; i++)
{
var tenantId = $"T{i}";
using (var db = multiDbFactory.OpenTenant(tenantId))
InitDb(db, tenantId, $"ACME {tenantId} inc.");
}
GlobalRequestFilters.Add((req, res, dto) =>
{
var forTennant = dto as IForTenant;
if (forTennant != null)
RequestContext.Instance.Items.Add("TenantId", forTennant.TenantId);
});
}
public void InitDb(IDbConnection db, string tenantId, string company)
{
db.DropAndCreateTable<TenantConfig>();
db.Insert(new TenantConfig { Id = tenantId, Company = company });
}
这样核心代码就完成了,我们用postman调用试试看,是不是达到了预期的效果
body为空,租户Id没有设置,系统认为是默认的数据库TMaster,返回的是Master数据库中的config表信息
body中设置json参数{"name":"joy", "tenantId":"t1"},可以看到查询返回的是数据库T1的信息
我们再试验一下T2,body中设置json参数{"name":"peter", "tenantId":"t2"}
可以很惊喜的看到,查询的是数据库T2的信息
ServiceStack解决方案真是强大,本来一个复杂的多租户问题就这样轻易解决了,是不是很简单。这里例子用的都是sqlserver数据库,实际上每个租户可以使用不同的数据库。
最近一年很流行ABP解决方案,我想说的是ServiceStack解决方案也很优秀,甚至更加优秀,当你了解越多你就会惊叹当初作者的设计思路是多么的优秀,有兴趣的小伙伴可以一起挖掘和分享啊!
|