ASP.NET MVC 3中是否可以有多个依赖项解析器?

时间:2013-04-05 20:21:34

标签: asp.net-mvc-3 dependency-injection

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

2 个答案:

答案 0 :(得分:6)

有一种情况我可以想到有多个'容器'或'解析器'是有用的,这是多租户。通过多租户,您可以在同一个Web应用程序中运行多个客户(组织,拥有自己的一组用户),并根据登录,请求信息或域信息动态切换。

仍然,DependencyResolver.Current是 - 达林注意到 - 静止,所以你无能为力(或者应该做些什么)。但是,您可以在单个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);
    }
}

以下代码段显示了此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>();
}

答案 1 :(得分:2)

  

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

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

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

你似乎也在你的问题中提到了一些提供者,但遗憾的是你还没有特别提及,所以对这个提出评论有点困难。