租户IoC容器在ASP.NET Web API应用程序中
Autofac 3.0将具有MultitenantIntegration支持,其预览版本现已发布。 为了试用它,我使用以下配置创建了一个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
。 在这个阶段我有两个问题,我无法解决:
RequestParameterTenantIdentificationStrategy
框中用作TenantIdentificationStrategy,仅用于此演示应用程序。 我可以通过实施ITenantIdentificationStrategy
界面来创建自定义TenantIdentificationStrategy。 然而, TryIdentifyTenant
的方法ITenantIdentificationStrategy
让你依靠静态实例如HttpContext.Current
这是一件好事,因为我希望我的API被托管无关,我不在ASP.NET Web API环境想(我知道我可以将这项工作委托给托管层,但我宁愿不要)。 有没有另一种方式来实现这一点,我不会依赖一个静态实例? 我也有机会注册租户特定实例如下:
mtc.ConfigureTenant("tenant1", cb => cb.RegisterType<Foo>()
.As<IFoo>().InstancePerApiRequest());
但是,我的一个情况要求我通过构造函数参数传递承租人名称,并且我希望具有以下内容:
mtc.ConfigureTenant((cb, tenantName) => cb.RegisterType<Foo>()
.As<IFoo>()
.WithParameter("tenantName", tenantName)
.InstancePerApiRequest());
目前没有这样的API。 还有另外一种方法可以达到这个要求吗?或者这种要求没有任何意义?
多租户支持已经有很长时间了,只是3.0版本是我们第一次为它开发NuGet软件包。 :)
正如文件所述, RequestParameterTenantIdentificationStrategy
只是一个非常简单的例子,显示了一种可能的(而不是推荐的 )方法来识别租户。 您必须自己选择如何根据运营环境来识别租户。 它可能来自web.config
值,环境变量或当前环境中的其他东西。 如果你不想使用HttpContext.Current
,不要。 这取决于你从哪里获得信息。
(有关RPTIStrategy
- 不推荐的部分是使用查询字符串或请求参数作为租户ID机制。我在生产应用程序中使用HttpContext
并且它工作正常。只有很多可以在您拥有之前抽象出来实际触摸裸机。)
提供您要求的lambda注册语法是没有办法的,主要是因为租户没有通过解析过程。 解决过程是:
这是故意简单和类似于现有的操作。 在解决的时候,属于租户的子生命周期范围被标记为租户ID,但解析操作不知道租户ID ......所以lambda不起作用(并且可能不会很快就会发生,因为它会改变Autofac工作方式的基础内部结构)。
要完成您要查找的内容,您可以在注册时使用InstancePerTenant
扩展名的组合...
var builder = new ContainerBuilder();
builder.RegisterType<Foo>().As<IFoo>().InstancePerTenant();
...并将ITenantIdentificationStrategy
注册为ITenantIdentificationStrategy
中的依赖项。
builder.Register(myIdStrategy).As<ITenantIdentificationStrategy>();
然后让您的班级直接采用ITenantIdentificationStrategy
而不是租户ID。 改用策略来取得租户ID。
如果你真的想变得有趣,你可以注册一个解析ID策略的键控lambda,然后获得租户ID。 然后,您可以像添加参数注册一样对象,但使用键控服务。 (我现在要回忆起来,所以你必须仔细检查我的语法,但它会是这样的......)
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();
再一次,你会想再次检查我,但我很确定(或一个小的变化)应该工作,以获得你想要的。
链接地址: http://www.djcxy.com/p/67749.html上一篇: tenant IoC Container in an ASP.NET Web API Application
下一篇: Calling python script from TCL and creating a file atomically