Autofac,运行时添加租户的最佳做法?

时间:2017-02-06 12:48:44

标签: c# model-view-controller autofac multi-tenant

我正在使用多租户容器,并且每个租户都在InstancePerLifeTime范围内注册了自己的数据库+ connectionstring。使用子域标识租户,子域使用生成的数据库名称映射到“主数据库”。

现在我有两个用例:

用例A:创建新租户: 有人用公司名称填写注册表,提交,提交后我们生成一个新的数据库,并且该租户应该能够访问companyname.domain.com下的应用程序

但是,我们希望在不重新启动影响所有当前租户的应用程序的情况下这样做。

假设我想添加一个新的租户,运行时。在不重新启动应用程序的情况下注册它的最佳方法是什么?

起初我考虑过注册容器,将其注入我的MVC控制器,并添加新的注册运行时但在阅读了一些问题后,这似乎是不好的做法。

我还可以从Controller中获取DependencyResolver并从那里访问容器。是否有更好的做法?

用例B:按需注册

假设我们有大量租户,并希望在应用程序启动时阻止一次注册。当子域名可以与现有帐户匹配时,我们可以在第一次请求时在多租户容器中注册这些内容。

但这可能是过早的优化,因为基本上我们还没有很多租户。

但同样,这会导致运行时注册。

容器:

        var tenantIdentificationStrategy= new TenantIdentificationStrategy();
        var multitenantContainer = new MultitenantContainer(tenantIdentificationStrategy, builder.Build());
        var tenants = new[]
        {
            "companyA.domain",
            "localhost"
        };

        foreach (var id in tenants)
        {
            var databaseName = $"tenant-{id}";


            multitenantContainer.ConfigureTenant(id, b =>
            {
                // Init RavenDB 
                b.Register(context => new RavenDocumentSessionFactory(databaseName))
                    .InstancePerTenant()
                    .AsSelf();

                // Session per request
                b.Register(context => context.Resolve<RavenDocumentSessionFactory>()
                    .FindOrCreate(context.Resolve<IDocumentStore>()))
                    .As<IDocumentSession>()
                    .InstancePerLifetimeScope()
                    .OnRelease(x =>
                    {
                        x.SaveChanges();
                        x.Dispose();
                    });

            });
        }

1 个答案:

答案 0 :(得分:2)

您最好的办法是在某个地方保留对应用程序容器的静态引用,并从那里注册您的租户。这是非常常见的做法,因为您的租户注册码必须知道&#34;无论如何MultitenantContainer是什么,它不会改变你的汇编参考或传播&#34;知识&#34;容器周围的容量超过原本必须的容量。

  • 在应用启动时创建多租户容器。
  • 注册您已了解的租户。
  • 将容器存放在全局可访问的静态属性中。
  • 需要注册租户时引用静态属性。