tug*_*erk 8 asp.net dependency-injection autofac multi-tenant 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);
}
}
Run Code Online (Sandbox Code Playgroud)
它完成工作并根据租户创建LoggerService实例ILoggerService.在这个阶段我有两个问题,我无法解决:
RequestParameterTenantIdentificationStrategy在这里提供的开箱即用作此演示应用程序的TenantIdentificationStrategy.我可以通过实现ITenantIdentificationStrategy接口来创建我的自定义TenantIdentificationStrategy .但是,这种TryIdentifyTenant方法ITenantIdentificationStrategy会让你依赖静态实例,例如HttpContext.Current我在ASP.NET Web API环境中不需要的东西,因为我希望我的API能够托管不可知(我知道我可以将这项工作委托给托管层,但我宁愿不去).还有另一种方法可以实现这一点,我不会依赖静态实例吗?我也有机会注册租户特定实例如下:
mtc.ConfigureTenant("tenant1", cb => cb.RegisterType<Foo>()
.As<IFoo>().InstancePerApiRequest());
Run Code Online (Sandbox Code Playgroud)
但是,我的一个情况要求我通过构造函数参数传递租户名称,我希望有类似下面的内容:
mtc.ConfigureTenant((cb, tenantName) => cb.RegisterType<Foo>()
.As<IFoo>()
.WithParameter("tenantName", tenantName)
.InstancePerApiRequest());
Run Code Online (Sandbox Code Playgroud)
目前没有这样的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();
Run Code Online (Sandbox Code Playgroud)
...并ITenantIdentificationStrategy在容器中注册为依赖项.
builder.Register(myIdStrategy).As<ITenantIdentificationStrategy>();
Run Code Online (Sandbox Code Playgroud)
然后让您的班级ITenantIdentificationStrategy直接获取租户ID而不是租户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();
Run Code Online (Sandbox Code Playgroud)
再一次,你会想要仔细检查我,但我很确定(或一个小变化)应该能够帮助你获得你想要的东西.
| 归档时间: |
|
| 查看次数: |
4299 次 |
| 最近记录: |