ASP.NET MVC 3 中是否可以有多个依赖解析器(类似于 ModelBinders 和 Providers 的情况)?
2 回答
在一种情况下,我可以想到拥有多个“容器”或“解析器”的地方是有用的,那就是多租户。通过多租户,您可以在同一个 Web 应用程序中运行多个客户(组织,拥有自己的用户集),并根据登录名、请求信息或域信息动态切换。
尽管如此,DependencyResolver.Current
正如 Darin 所指出的那样,是静态的,因此您无能为力(或应该对此做些什么)。但是,您可以将多个容器隐藏在单个IDependencyResolver
抽象后面,并根据某些标准返回一个实现。它可能看起来像这样:
public class MultiTenantDependencyResolver
: IDependencyResolver
{
Func<int> tenantIdSelector,;
IDictionary<int, IDependencyResolver> tenantResolvers;
public MultiTenantDependencyResolver(
Func<int> tenantIdSelector,
IDictionary<int, IDependencyResolver> tenantResolvers)
{
this.tenantIdSelector = tenantIdSelector;
this.tenantResolvers= tenantResolvers;
}
private IDependencyResolver CurrentResolver
{
get { return this.tenantResolvers[tenantIdSelector()]; }
}
public object GetService(Type serviceType)
{
return this.CurrentResolver.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.CurrentResolver.GetAllInstances(serviceType);
}
}
以下代码片段显示了 this 的用法MultiTenantDependencyResolver
:
var tenantResolvers = new Dictionary<int, IDependencyResolver>
{
{ Tenants.AbcId, BuildResolver(RegisterForTenantAbc) },
{ Tenants.KlmId, BuildResolver(RegisterForTenantKlm) },
{ Tenants.XyzId, BuildResolver(RegisterForTenantXyz) },
};
var multiTenantResolver = new MultiTenantResolver(
() => GetTenantIdFromUrl(), tenantResolvers);
DependencyResolver.SetResolver(multiTenantResolver);
private static int GetTenantIdFromUrl()
{
// TODO: return tenant id
}
private static IDependencyResolver BuildResolver(
Action<IKernel> tenantSpecificRegistrations)
{
var kernel = new Kernel();
// TODO: Tenant agnostic registrations. For instance
kernel.Bind<ITimeProvider>().To<SystemTimeProvider>();
tenantSpecificRegistrations(kernel);
return new NinjectDependencyResolver(kernel);
}
private static void RegisterForTenantAbc(IKernel kernel)
{
// TODO: regisrations for ABC tenant. For instance
kernel.Bind<ILogger>().To<AbcTenantLogger>();
}
ASP.NET MVC 3 中是否可以有多个依赖解析器(类似于 ModelBinders 和 Providers 的情况)?
不,这是不可能的。这DependencyResolver.Current
是一个静态属性,只能分配一个解析器。据说在应用程序中拥有多个依赖解析器几乎没有任何意义。这个想法是所有依赖项都由依赖注入框架管理,例如 Unity、Ninject 或 StructureMap。然后,您将拥有一个自定义依赖关系解析器,包装您选择的 DI 框架,ASP.NET MVC 将使用该框架在执行管道的各种对象中注入依赖关系。
您正在将其与问题中的模型绑定器进行比较,但这种比较是不公平的,因为模型绑定器与它旨在绑定的特定类型相关。基本上,您可以为多个视图模型拥有许多自定义模型绑定器。
您似乎在您的问题中也提到了一些提供者,但不幸的是,您并没有非常具体,因此对此发表评论有点困难。