如何将 Autofac 模块与多租户容器一起使用?
How to use Autofac Modules with Muti-Tenant container?
如何使用 Autofac 的 Modules combined with the Multitenant 包?
这是我对 Autofac 的引导部分:
var builder = new ContainerBuilder();
// only very basic common registrations here...
// everything else is in modules
// Register the Autofac module for xml configuration as last
// module to allow (emergency) overrides.
builder.RegisterModule(new ConfigurationSettingsReader());
// create container for IoC
this.container = builder.Build();
// check for tenant strategy -> if exists, go multi-tenant
if (this.container.IsRegistered<ITenantIdentificationStrategy>())
{
var tenantIdentificationStrategy = this.container
.Resolve<ITenantIdentificationStrategy>();
this.container = new MultitenantContainer(tenantIdentificationStrategy,
this.container);
// how to use xml modules instead of manually register at this point?
}
else
{ ... }
我不想调用
container.ConfigureTenant('1', b => b.RegisterType<Tenant1Dependency>()
.As<IDependency>()
.InstancePerDependency());
在引导程序中(不需要对此有所了解)。
相反,我想做这样的事情:
public class TenantModule : Module
{
protected override void Load(ContainerBuilder builder)
{
container.ConfigureTenant('1', b => b.RegisterType<Tenant1Dependency>()
.As<IDependency>()
.InstancePerDependency());
container.ConfigureTenant('2', b => b.RegisterType<Tenant2Dependency>()
.As<IDependency>()
.InstancePerDependency());
...
我的第一个想法是在为特殊租户注册东西时检查:
public class TenantModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register((c, p) => {
var s = c.Resolve<ITenantIdentificationStrategy>();
if (s != null)
{
var id = s.IdentifyTenant<string>();
...
}
});
我可以检查 id 并仅在 id 适合时注册,但如果 id 不匹配怎么办 return?无效的?什么都不做?在我看来 strange/horrible 的代码和
之类的东西
builder.Register("1", (context, parameters) => ...
感觉更自然。但我不知道如何使用 Autofac 开箱即用。我错过了什么?你是怎么解决这个问题的?
错过了 ConfigureTenant 还传递 containerBuilder 的要点,它允许注册租户特定的 ConfigurationSectionReader。所以一个选项是有一个额外的 customer/tenant 特定的 ConfigurationSection:
mtc.ConfigureTenant("mytenant1",
containerBuilder =>
{
containerBuilder.RegisterModule(new ConfigurationSettingsReader("mytenant1"));
}
);
mtc.ConfigureTenant("mytenant2",
containerBuilder =>
{
containerBuilder.RegisterModule(new ConfigurationSettingsReader("mytenant2"));
}
);
这也让我想到我可以首先解决租户识别策略,获取标识符并仅为当前租户进行注册(如客户特定 bootstrap):
var tenantIdentificationStrategy = container.Resolve<ITenantIdentificationStrategy>();
var tid = tenantIdentificationStrategy.IdentifyTenant<string>();
mtc.ConfigureTenant(tid ,
containerBuilder =>
{
containerBuilder.RegisterModule(new ConfigurationSettingsReader(tid));
// or something like that which identifies the tenant config section
}
);
或者我可以将它放入一个简单的 foreach 中,为所有可用的租户进行注册(但这在大多数情况下听起来很奇怪,因为在 bootstrapping 部分一次只会解析一个租户,也许对于其他值得一提的特殊情况)。
有什么更好的主意吗?我会投票赞成更好的想法...;-)
如何使用 Autofac 的 Modules combined with the Multitenant 包?
这是我对 Autofac 的引导部分:
var builder = new ContainerBuilder();
// only very basic common registrations here...
// everything else is in modules
// Register the Autofac module for xml configuration as last
// module to allow (emergency) overrides.
builder.RegisterModule(new ConfigurationSettingsReader());
// create container for IoC
this.container = builder.Build();
// check for tenant strategy -> if exists, go multi-tenant
if (this.container.IsRegistered<ITenantIdentificationStrategy>())
{
var tenantIdentificationStrategy = this.container
.Resolve<ITenantIdentificationStrategy>();
this.container = new MultitenantContainer(tenantIdentificationStrategy,
this.container);
// how to use xml modules instead of manually register at this point?
}
else
{ ... }
我不想调用
container.ConfigureTenant('1', b => b.RegisterType<Tenant1Dependency>()
.As<IDependency>()
.InstancePerDependency());
在引导程序中(不需要对此有所了解)。
相反,我想做这样的事情:
public class TenantModule : Module
{
protected override void Load(ContainerBuilder builder)
{
container.ConfigureTenant('1', b => b.RegisterType<Tenant1Dependency>()
.As<IDependency>()
.InstancePerDependency());
container.ConfigureTenant('2', b => b.RegisterType<Tenant2Dependency>()
.As<IDependency>()
.InstancePerDependency());
...
我的第一个想法是在为特殊租户注册东西时检查:
public class TenantModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register((c, p) => {
var s = c.Resolve<ITenantIdentificationStrategy>();
if (s != null)
{
var id = s.IdentifyTenant<string>();
...
}
});
我可以检查 id 并仅在 id 适合时注册,但如果 id 不匹配怎么办 return?无效的?什么都不做?在我看来 strange/horrible 的代码和
之类的东西builder.Register("1", (context, parameters) => ...
感觉更自然。但我不知道如何使用 Autofac 开箱即用。我错过了什么?你是怎么解决这个问题的?
错过了 ConfigureTenant 还传递 containerBuilder 的要点,它允许注册租户特定的 ConfigurationSectionReader。所以一个选项是有一个额外的 customer/tenant 特定的 ConfigurationSection:
mtc.ConfigureTenant("mytenant1",
containerBuilder =>
{
containerBuilder.RegisterModule(new ConfigurationSettingsReader("mytenant1"));
}
);
mtc.ConfigureTenant("mytenant2",
containerBuilder =>
{
containerBuilder.RegisterModule(new ConfigurationSettingsReader("mytenant2"));
}
);
这也让我想到我可以首先解决租户识别策略,获取标识符并仅为当前租户进行注册(如客户特定 bootstrap):
var tenantIdentificationStrategy = container.Resolve<ITenantIdentificationStrategy>();
var tid = tenantIdentificationStrategy.IdentifyTenant<string>();
mtc.ConfigureTenant(tid ,
containerBuilder =>
{
containerBuilder.RegisterModule(new ConfigurationSettingsReader(tid));
// or something like that which identifies the tenant config section
}
);
或者我可以将它放入一个简单的 foreach 中,为所有可用的租户进行注册(但这在大多数情况下听起来很奇怪,因为在 bootstrapping 部分一次只会解析一个租户,也许对于其他值得一提的特殊情况)。
有什么更好的主意吗?我会投票赞成更好的想法...;-)