简体   繁体   中英

ParameterOverride failing on System.Type parameter

I'm attempting to use a ParameterOverride with Unity 2.0. It works fine as long as the parameter I'm supplying is not a System.Type.

In the following test program, I am injecting the constructor to MyClass<T> with an integer parameter when the generic parameter T is an int, and with a Type parameter when T is System.Type. In the output that follows, you'll see that it handles the integer just fine, but seems to think that typeof(MyClassForParam) is an actual MyClassForParam object, not the type. Any ideas?

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();
        }
    }
}

Output follows:

Injecting an integer parameter.
12345

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

Exception occurred while:

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'.

At the time of the exception, the container was:

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)

Unity gives special treatment to Type parameter definitions. See this post by Krzysztof Kozmic for more details: http://kozmic.pl/2008/12/03/unity-framework-and-the-principle-of-the-least-surprise/

I ran into the same issue after some spelunking in Unity I found that you can override the default type resolution behavior by wrapping the naked type argument with an InjectionParameter:

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

The constructor for ParameterOverride uses InjectionParameterValue.ToParameter() which will respect any predefined sub-class of InjectionParameterValue. This method should also work when using a PropertyOverride which uses the same method during construction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM