4

ASP.NET MVC 3 中是否可以有多个依赖解析器(类似于 ModelBinders 和 Providers 的情况)?

4

2 回答 2

7

在一种情况下,我可以想到拥有多个“容器”或“解析器”的地方是有用的,那就是多租户。通过多租户,您可以在同一个 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>();
}
于 2013-04-05T21:57:48.513 回答
2

ASP.NET MVC 3 中是否可以有多个依赖解析器(类似于 ModelBinders 和 Providers 的情况)?

不,这是不可能的。这DependencyResolver.Current是一个静态属性,只能分配一个解析器。据说在应用程序中拥有多个依赖解析器几乎没有任何意义。这个想法是所有依赖项都由依赖注入框架管理,例如 Unity、Ninject 或 StructureMap。然后,您将拥有一个自定义依赖关系解析器,包装您选择的 DI 框架,ASP.NET MVC 将使用该框架在执行管道的各种对象中注入依赖关系。

您正在将其与问题中的模型绑定器进行比较,但这种比较是不公平的,因为模型绑定器与它旨在绑定的特定类型相关。基本上,您可以为多个视图模型拥有许多自定义模型绑定器。

您似乎在您的问题中也提到了一些提供者,但不幸的是,您并没有非常具体,因此对此发表评论有点困难。

于 2013-04-05T21:09:48.380 回答