Is it possible to have multiple dependency resolvers in ASP.NET MVC 3?

前端 未结 2 1921
悲哀的现实
悲哀的现实 2021-02-10 09:00

Is it possible to have more than one dependency resolver in ASP.NET MVC 3 (similar to the case of ModelBinders and Providers)?

2条回答
  •  Happy的楠姐
    2021-02-10 09:35

    There is one scenario that I could think of where having multiple 'containers' or 'resolvers' is useful and that is multi-tenancy. With multi tenancy you run multiple customers (organizations, with their own set of users) in the same web application, and dynamically switch based on the login, request info, or domain info.

    Still, DependencyResolver.Current is -as Darin noted- static, so there's nothing you can (or should do about this). However, you could hide multiple containers behind a single IDependencyResolver abstraction and return an implementation based on some criteria. It might look like this:

    public class MultiTenantDependencyResolver 
        : IDependencyResolver
    {
        Func tenantIdSelector,;
        IDictionary tenantResolvers;
    
        public MultiTenantDependencyResolver(
            Func tenantIdSelector,
            IDictionary 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 GetServices(Type serviceType)
        {
            return this.CurrentResolver.GetAllInstances(serviceType);
        }
    }
    
    
    

    The following code snippet shows the usage of this MultiTenantDependencyResolver:

    var tenantResolvers = new Dictionary
    {
        { 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 tenantSpecificRegistrations)
    {
        var kernel = new Kernel();
    
        // TODO: Tenant agnostic registrations. For instance
        kernel.Bind().To();
    
        tenantSpecificRegistrations(kernel);
    
        return new NinjectDependencyResolver(kernel);
    }
    
    private static void RegisterForTenantAbc(IKernel kernel)
    {
        // TODO: regisrations for ABC tenant. For instance
        kernel.Bind().To();
    }
    

    提交回复
    热议问题