Resolving named registration using Unity 2 in DefaultControllerFactory

橙三吉。 提交于 2020-01-04 06:06:09

问题


I have an issue with resolving named registrations of registered types in Unity 2 using ASP.NET MVC 3 with DI set in DefaultControllerFactory.

In one assembly I have defined Unity container with registration types and named registrations

public class VisUnityContainer : UnityContainer
{
    public IUnityContainer RegisterVisComponents()
    {
         // register types
         this               
             .RegisterType<ICompanyService, CompanyService>()
             .RegisterType<ICompanyService, TestCompanyService>( "2" );
    }
}

and in my MVC project I have inherited DefaultControllerFactory i am resolving types and passing VisUnityContainer

public class UnityControllerFactory : DefaultControllerFactory
{
    private readonly IUnityContainer unityContainer;

    public UnityControllerFactory( IUnityContainer unityContainer )
    {
        // set contracts
        if( unityContainer == null )
            throw new ArgumentNullException( null, "Unity container is not initialized." );

        // set associations
        this.unityContainer = unityContainer;
    }

    protected override IController GetControllerInstance( RequestContext requestContext, Type controllerType )
    {
        // set contracts
        if( controllerType == null )
            throw new HttpException( 404, String.Format(  "The controller for path '{0}' could not be found or it does not implement IController.",
                     requestContext.HttpContext.Request.Path ) );
        if( !typeof( IController ).IsAssignableFrom( controllerType ) )
            throw new ArgumentException( String.Format( "Type requested is not a controller: {0}", controllerType.Name ) );

        // action result
        IController controller;

        // company law
        string companyLaw = String.Empty;

        // set user properties
        if( Thread.CurrentPrincipal != null &&
            Thread.CurrentPrincipal.Identity.Name != null &&
            !String.IsNullOrWhiteSpace( Thread.CurrentPrincipal.Identity.Name ) )
        {
            // set culture for law of companies region
            CultureInfo cultureInfo = new CultureInfo( Profile.GetCurrent().CompanyState );

            // set language
            CultureInfo uiCultureInfo = new CultureInfo( Profile.GetCurrent().UserLanguage );

            // set dates etc.
            Thread.CurrentThread.CurrentCulture = cultureInfo;

            // get proper resource file
            Thread.CurrentThread.CurrentUICulture = uiCultureInfo;

            // set company law
            companyLaw = Profile.GetCurrent().CompanyLaw;
        }

        try
        {
            // resolve container
            controller = this.unityContainer.Resolve( controllerType, companyLaw ) as IController;
        }
        catch( Exception )
        {
            // throw exception
            throw new InvalidOperationException( String.Format( "Error resolving controller {0}", controllerType.Name ) );
        }

        // action end
        return controller;

    }
}

The problem is with line

controller = this.unityContainer.Resolve( controllerType, companyLaw ) as IController;

While companyLaw is equal 2 it doesn't resolve named registration TestCompanyService, but always CompanyService. If I also set CompanyService with some named registration, it throws an error saying it can't resolve a type.

Also, if I try manually to resolve a type like

var test = this.unityContainer.Resolve<ICompanyService>( companyLaw );

It returns the correct type.

Does anybody have an idea what's wrong?


回答1:


Container.Resolve(type,string)

and

Container.Resolve<T>(string)

aren't different methods.

Resolve(string) is actually an extension method that, internally, calls Container.Resolve(type,string).

Looking at the code, is "controllerType" a class or interface? If "controllerType" is a class (CompanyService) rather than an interface (ICompanyService) it will always resolve to CompanyService. It would also explain why it errors when you try to

Resolve(controllerType,"2")

because what you're actually saying here is:

container.Resolve(typeof(CompanyService),"2");

which doesn't exist.

This would also explain why it works when you call:

container.Resolve<ICompanyService>("2");

Because you're setting the correct interface here

So, short answer:

I think you're passing the concrete class type rather than the interface to Unity. Should be fairly easy to check.



来源:https://stackoverflow.com/questions/10918532/resolving-named-registration-using-unity-2-in-defaultcontrollerfactory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!