gpt4 book ai didi

asp.net - ASP.NET Web API 应用程序中的 Autofac Multi-Tenancy IoC 容器

转载 作者:行者123 更新时间:2023-12-02 18:24:14 27 4
gpt4 key购买 nike

Autofac 3.0将会有一个MultitenantIntegration支持和its preview release is out现在。为了进行尝试,我创建了一个具有以下配置的 ASP.NET Web API 应用程序:

public class Global : System.Web.HttpApplication {

protected void Application_Start(object sender, EventArgs e) {

var config = GlobalConfiguration.Configuration;
config.Routes.MapHttpRoute("Default", "api/{controller}");
RegisterDependencies(config);
}

public void RegisterDependencies(HttpConfiguration config) {

var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

// creates a logger instance per tenant
builder.RegisterType<LoggerService>().As<ILoggerService>().InstancePerTenant();

var mtc = new MultitenantContainer(
new RequestParameterTenantIdentificationStrategy("tenant"),
builder.Build());

config.DependencyResolver = new AutofacWebApiDependencyResolver(mtc);
}
}

它完成工作并为每个租户创建一个 LoggerService 实例作为 ILoggerService。我现阶段有两个问题无法解决:

  1. 我使用此处提供的开箱即用的 RequestParameterTenantIdentificationStrategy 作为此演示应用程序的 TenantIdentificationStrategy。我可以通过实现 ITenantIdentificationStrategy 接口(interface)来创建自定义 TenantIdentificationStrategy。但是,ITenantIdentificationStrategyTryIdentifyTenant 方法使您依赖于静态实例,例如 HttpContext.Current,这是我不想要的ASP.NET Web API 环境,因为我希望我的 API 与托管无关(我知道我可以将这项工作委托(delegate)给托管层,但我宁愿不这样做)。是否有另一种方法可以不依赖静态实例来实现此目的?
  2. 我还有机会注册租户特定实例,如下所示:

    mtc.ConfigureTenant("tenant1", cb => cb.RegisterType<Foo>()
    .As<IFoo>().InstancePerApiRequest());

    但是,我的一种情况要求我通过构造函数参数传递租户名称,我希望有如下所示的内容:

    mtc.ConfigureTenant((cb, tenantName) => cb.RegisterType<Foo>()
    .As<IFoo>()
    .WithParameter("tenantName", tenantName)
    .InstancePerApiRequest());

    目前没有这样的API。有没有其他方法可以实现这个或者这种要求没有任何意义?

最佳答案

Multi-Tenancy 支持已经提供很长时间了,只是 3.0 是我们第一次为其提供 NuGet 包。 :)

如文档所述,RequestParameterTenantIdentificationStrategy 只是一个非常简单的示例,展示了一种可能的(且不推荐)识别租户的方法。您必须根据运营环境自行选择如何识别租户。它可能来自 web.config 值、环境变量或当前环境中的其他内容。如果您不想使用 HttpContext.Current,请不要使用。您可以选择从何处获取该信息。

(关于 RPTIStrategy 的注释 - 不推荐的部分是使用查询字符串或请求参数作为租户 ID 机制。我在生产中使用 HttpContext应用程序,它工作得很好。在你真正接触裸机之前,你只能抽象出这么多。)

无法开箱即用地提供您要求的 lambda 注册语法,主要是因为租户未通过解析过程。解决过程为:

  1. 通过策略确定租户。
  2. 查找租户配置的生命周期范围。
  3. 使用标准 Autofac Resolve 样式语法。

它故意简单且与现有操作类似。在解析时,属于租户的子生命周期范围被租户 ID 标记,但解析操作不知道租户 ID...因此 lambda 不会工作(而且可能不会很快,因为如果它工作的话,它会改变 Autofac 工作方式的基本内部结构)。

要实现您想要的目标,您可以在注册时结合使用 InstancePerTenant 扩展...

var builder = new ContainerBuilder();
builder.RegisterType<Foo>().As<IFoo>().InstancePerTenant();

...并将 ITenantIdentificationStrategy 注册为容器中的依赖项。

builder.Register(myIdStrategy).As<ITenantIdentificationStrategy>();

然后让您的类采用 ITenantIdentificationStrategy 而不是直接采用租户 ID。请改用该策略来获取租户 ID。

如果您真的想要变得更奇特,您可以注册一个解析 ID 策略的键控 lambda,然后获取租户 ID。然后,您可以像以前一样向对象添加参数注册,但使用 key 服务。 (我现在要靠内存,所以你必须在这里仔细检查我的语法,但它会是这样的......)

builder.Register(c => 
{ var s = c.Resolve<ITenantIdentificationStrategy>();
object id;
s.TryIdentifyTenant(out id);
return id;
}).Keyed<object>("tenantId");

builder.RegisterType<Foo>()
.As<IFoo>()
.WithParameter(
(pi, c) => pi.Name == "tenantId",
(pi, c) => c.ResolveKeyed<object>("tenantId"))
.InstancePerApiRequest();

同样,您需要仔细检查我的情况,但我很确定(或细微的变化)应该能够满足您的需求。

关于asp.net - ASP.NET Web API 应用程序中的 Autofac Multi-Tenancy IoC 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14013885/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com