Ошибка ParameterOverride для параметра System.Type - PullRequest
7 голосов
/ 09 апреля 2011

Я пытаюсь использовать ParameterOverride с Unity 2.0. Он работает нормально, пока параметр, который я предоставляю, не является System.Type.

В следующей тестовой программе я внедряю конструктор в MyClass<T> с целочисленным параметром, когда универсальный параметр T является целым числом, и с параметром Type, когда T является System.Type. В следующем выводе вы увидите, что он прекрасно обрабатывает целое число, но, похоже, думает, что typeof(MyClassForParam) - это фактический MyClassForParam объект, а не тип. Есть идеи?

namespace UnityParameterOverride
{
    interface IMyClass
    {
    }

    public class MyClass<T> : IMyClass
    {
        public MyClass(T myParam)
        {
            Console.WriteLine("{0}", myParam);
        }
    }

    public class MyClassForParam
    {
        public MyClassForParam() { }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer unity = new UnityContainer();
            try
            {
                // Works fine: prints 12345
                Console.WriteLine("Injecting an integer parameter.");
                unity.RegisterType<IMyClass, MyClass<int>>();
                unity.Resolve<IMyClass>(new ParameterOverride("myParam", 12345));

                // Fails: Seems to think that the parameter is an actual MyClassForParam instead of the type of that class.
                Console.WriteLine();
                Console.WriteLine("Injecting a Type parameter.");
                unity.RegisterType<IMyClass, MyClass<Type>>();
                unity.Resolve<IMyClass>(new ParameterOverride("myParam", typeof(MyClassForParam)));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    }
}

Вывод следует:

Injecting an integer parameter.
12345

Injecting a Type parameter. ----
Resolution of the dependency failed, type = "UnityParameterOverride.IMyClass", name = "(none)".

Исключение произошло, когда:

Exception occurred while: Resolving parameter "myParam" of constructor UnityParameterOverride.MyClass`1[[System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Type myParam).
Exception is: InvalidCastException - Unable to cast object of type 'UnityParameterOverride.MyClassForParam' to type 'System.Type'.

На момент исключения контейнер был:

Resolving UnityParameterOverride.MyClass1[System.Type],(none) (mapped from Un ityParameterOverride.IMyClass, (none)) Resolving parameter "myParam" of constructor UnityParameterOverride.MyClass1[ [System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c5 61934e089]](System.Type myParam)

Ответы [ 2 ]

8 голосов
/ 09 апреля 2011

Unity предоставляет особый подход к определениям параметров типа.Смотрите это сообщение от Krzysztof Kozmic для более подробной информации: http://kozmic.pl/2008/12/03/unity-framework-and-the-principle-of-the-least-surprise/

4 голосов
/ 06 апреля 2012

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

new ParameterOverride("typeParameterArgument",new InjectionParameter(typeof(Type),typeof(MyNamespace.MyClassUsedAsInjectedTypeArgument)))

Конструктор для ParameterOverride использует InjectionParameterValue.ToParameter (), который будет учитывать любой предопределенный подкласс InjectionParameterValue.Этот метод также должен работать при использовании PropertyOverride, который использует тот же метод во время построения.

...