Разрешение именованной регистрации с использованием Unity 2 в DefaultControllerFactory

У меня есть проблема с разрешением именованных регистраций зарегистрированных типов в Unity 2 с использованием ASP.NET MVC 3 с DI, установленным в DefaultControllerFactory.

В одной сборке я определил контейнер Unity с типами регистрации и именованными регистрациями.

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

и в моем проекте MVC я унаследовал DefaultControllerFactory, я разрешаю типы и передаю 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;

    }
}

Проблема с линией

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

Хотя companyLaw равно 2, оно не разрешает именованную регистрацию TestCompanyService, но всегда CompanyService. Если я также установлю CompanyService с некоторой именованной регистрацией, он выдаст ошибку, говорящую, что он не может разрешить тип.

Кроме того, если я пытаюсь вручную разрешить такой тип, как

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

Возвращает правильный тип.

У кого-нибудь есть идея, что не так?

1 ответ

Container.Resolve(type,string)

а также

Container.Resolve<T>(string)

не разные методы.

Resolve (строка) на самом деле является методом расширения, который внутренне вызывает Container.Resolve(тип, строка).

Глядя на код, "controllerType" это класс или интерфейс? Если "controllerType" является классом (CompanyService), а не интерфейсом (ICompanyService), он всегда будет преобразован в CompanyService. Было бы также объяснить, почему это ошибки, когда вы пытаетесь

Resolve(controllerType,"2")

потому что вы на самом деле говорите:

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

который не существует

Это также объясняет, почему это работает, когда вы звоните:

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

Потому что вы устанавливаете правильный интерфейс здесь

Итак, короткий ответ:

Я думаю, что вы передаете конкретный тип класса, а не интерфейс для Unity. Должно быть довольно легко проверить.

Другие вопросы по тегам