【问题标题】:How to use Autofac Modules with Muti-Tenant container?如何将 Autofac 模块与多租户容器一起使用?
【发布时间】:2015-04-13 19:28:00
【问题描述】:

如何结合使用 Autofac 的 ModulesMultitenant 包?

这是我对 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 不匹配,返回什么?无效的?什么都不做?对我来说,代码看起来很奇怪/可怕

builder.Register("1", (context, parameters) => ...

感觉更自然。但我不知道如何使用 Autofac 开箱即用地实现这一点。我错过了什么?你是怎么解决这个问题的?

【问题讨论】:

    标签: c# autofac multi-tenant autofac-module


    【解决方案1】:

    忽略了 ConfigureTenant 还通过允许注册租户特定 ConfigurationSectionReader 的 containerBuilder 的观点。所以一个选项是有一个额外的客户/租户特定的 ConfigurationSection:

       mtc.ConfigureTenant("mytenant1",
             containerBuilder =>
             {
                 containerBuilder.RegisterModule(new ConfigurationSettingsReader("mytenant1"));
             }
       );
    
       mtc.ConfigureTenant("mytenant2",
             containerBuilder =>
             {
                 containerBuilder.RegisterModule(new ConfigurationSettingsReader("mytenant2"));
             }
       );
    

    这也让我想到我可以先解决租户识别策略,获取标识符并只为当前租户进行注册(如客户特定的引导程序):

       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 中,以便为所有可用租户进行注册(但这在大多数情况下听起来很奇怪,因为在它的引导部分有时会解决一个租户,也许对于其他值得一提的特殊情况提及)。

    有更好的想法吗?我会投票支持更好的想法... ;-)

    【讨论】:

    • 这个解决方案对我来说听起来不错。您正在考虑哪种问题?顺便说一句,如果您有一个大型应用程序,我建议您查看 Multitenant 扩展的源代码,它非常简单,并且在某些情况下,最好将它分叉并根据您自己的情况进行调整。这就是我为大型应用程序所做的。
    • @CyrilDurand 分叉的原因是什么?
    • multitenant autofac 扩展非常小巧简单,我将它用作多租户应用程序的示例实现。我不记得我为什么不这样使用它,但我认为我需要更多的控制和更多的扩展点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 2012-12-10
    • 2023-01-12
    • 1970-01-01
    相关资源
    最近更新 更多