2011-04-08 7 views
7

Estoy intentando usar un ParameterOverride con Unity 2.0. Funciona bien siempre que el parámetro que estoy suministrando no sea un System.Type.ParameterOverride falla en el parámetro System.Type

En el siguiente programa de prueba, estoy inyectando el constructor a MyClass<T> con un parámetro entero cuando el parámetro genérico T es un int, y con un parámetro Type cuando T es System.Type. En el resultado que sigue, verá que maneja bien el entero, pero parece pensar que typeof(MyClassForParam) es un objeto real MyClassForParam, no el tipo. ¿Algunas 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(); 
     } 
    } 
} 

de salida sigue:

Injecting an integer parameter. 
12345 

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

producido una excepción al:

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

En el momento de la excepción, el recipiente fue:

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) 

Respuesta

8

Unidad da un tratamiento especial para escribir el parámetro defin itions. Ver este mensaje por Krzysztof Kozmic para más detalles: http://kozmic.pl/2008/12/03/unity-framework-and-the-principle-of-the-least-surprise/

+2

** Perfecto ** ¡respuesta! De hecho, el ejemplo de Krzysztof Kozmic de inyectar un argumento Type en un ServiceHost es _exactly_ lo que estaba haciendo IRL. – LSpencer777

+1

Acabo de encontrar esto porque estaba teniendo el mismo problema. tratando de inyectar el ServiceType en un ServiceHost. –

4

me encontré con el mismo problema después de algún espeleología en la Unidad He descubierto que se puede reemplazar el comportamiento resolución tipo predeterminado envolviendo el argumento de tipo desnudo con una InjectionParameter:

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

El constructor para ParameterOverride usa InjectionParameterValue.ToParameter() que respetará cualquier subclase predefinida de InjectionParameterValue. Este método también debería funcionar cuando se utiliza una PropertyOverride que usa el mismo método durante la construcción.

+1

Gracias por el ejemplo. ¡Esto resolvió mi problema exacto! –

Cuestiones relacionadas