解决DefaultControllerFactory使用Unity 2名为注册 [英] Resolving named registration using Unity 2 in DefaultControllerFactory

查看:145
本文介绍了解决DefaultControllerFactory使用Unity 2名为注册的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,使用ASP.NET MVC 3与DI在DefaultControllerFactory设置解决注册类型在Unity 2的命名注册。

在一个程序集我已经定义了统一的容器,注册类型和注册名为

 公共类VisUnityContainer:UnityContainer
{
    公共IUnityContainer RegisterVisComponents()
    {
         //注册类型
         这个
             .RegisterType< ICompanyService,CompanyService>()
             .RegisterType&所述; ICompanyService,TestCompanyService>(2);
    }
}

在我的MVC项目我继承DefaultControllerFactory我正在解决的类型和传递VisUnityContainer

 公共类UnityControllerFactory:DefaultControllerFactory
{
    私人只读IUnityContainer unityContainer;    公共UnityControllerFactory(IUnityContainer unityContainer)
    {
        //组合同
        如果(unityContainer == NULL)
            抛出新的ArgumentNullException(NULL,团结容器未初始化。);        //设置关联
        this.unityContainer = unityContainer;
    }    保护覆盖一个IController GetControllerInstance(RequestContext的RequestContext的,类型controllerType)
    {
        //组合同
        如果(controllerType == NULL)
            抛出新的HttpException(404的String.Format(以下简称控制器路径{0}找不到或没有实现一个IController。
                     requestContext.HttpContext.Request.Path));
        如果(!typeof运算(一个IController).IsAssignableFrom(controllerType))
            抛出新的ArgumentException(的String.Format(请求的类型不是控制器:{0},controllerType.Name));        //作用的结果
        一个IController控制器;        //公司法
        字符串companyLaw =的String.Empty;        //设置用户属性
        如果(= Thread.CurrentPrincipal中零和放大器;!&安培;
            Thread.CurrentPrincipal.Identity.Name = NULL&放大器;!&安培;
            !String.IsNullOrWhiteSpace(Thread.CurrentPrincipal.Identity.Name))
        {
            //集文化为企业区法
            的CultureInfo的CultureInfo =新的CultureInfo(Profile.GetCurrent()CompanyState);            //设置语言
            CultureInfo的uiCultureInfo =新的CultureInfo(Profile.GetCurrent()用户语言。);            //设置日期等。
            Thread.CurrentThread.CurrentCulture = CultureInfo的;            //得到适当的资源文件
            Thread.CurrentThread.CurrentUICulture = uiCultureInfo;            //设置公司法
            companyLaw = Profile.GetCurrent()CompanyLaw。
        }        尝试
        {
            //决心容器
            控制器= this.unityContainer.Resolve(controllerType,companyLaw)作为一个IController;
        }
        赶上(例外)
        {
            //抛出异常
            抛出新的InvalidOperationException异常(的String.Format(错误解决控制器{0},controllerType.Name));
        }        //行动结束
        返回控制器;    }
}

问题是与行

 控制器= this.unityContainer.Resolve(controllerType,companyLaw)作为一个IController;

虽然companyLaw等于2它不能解决命名注册TestCompanyService,但总是CompanyService。如果我还设置CompanyService和姓注册,它抛出一个错误说,它不能解析一个类型。

另外,如果我尝试手动解决一类像

  VAR测试= this.unityContainer.Resolve< ICompanyService>(companyLaw);

它返回正确的类型。

没有任何人有一个想法有什么不对?


解决方案

  Container.Resolve(类型,字符串)

  Container.Resolve< T>(字符串)

不是不同的方法。

解析(字符串)实际上是一个扩展方法,在内部,调用Container.Resolve(类型,字符串)。

纵观code,是controllerType一类或接口?如果controllerType是一个类(CompanyService),而不是一个接口(ICompanyService),它会始终解析为CompanyService。这也可以解释为什么它的错误,当您尝试

 解析(controllerType,2)

因为你实际上在这里说的是:

  container.Resolve(typeof运算(CompanyService),2);

不存在

这也可以解释为什么它的工作原理,当你调用:

  container.Resolve< ICompanyService>(2);

由于你在这里设置了正确的接口

所以,答案很简单:

我觉得你传递具体类类型,而不是界面统一。应该很容易检查。

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?

解决方案

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.

这篇关于解决DefaultControllerFactory使用Unity 2名为注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆