2010-11-03 1 views
1

J'ai une classe avec deux constructeurs, les deux constructeurs ont un paramètre. En raison de restrictions qui ne valent pas la peine d'être expliquées, je ne peux pas modifier les constructeurs ou utiliser une classe descendante.Unity.BuildUp impossible de désambiguïser

Je ne peux pas utiliser unity pour créer des instances de cette classe car Unity voit 2 constructeurs avec le même nombre de paramètres et se plaint de ne pas savoir lequel utiliser, ce qui est assez juste. Ainsi, au lieu que je crée l'instance moi-même et puis essayez d'utiliser UnityContainer.BuildUp()

var result = constructorInfo.Invoke(new object[] { content }); 
UnitContainer.BuildUp(result); 

Le code ci-dessus ne fixe aucune de mes propriétés [dépendance] ni un appel [InjectionMethod] si j'utiliser à la place .

var result = constructorInfo.Invoke(new object[] { content }); 
UnitContainer.BuildUp(typeOfObject, result); 

Cela jette une autre exception à propos des constructeurs ambigus, même si je ne lui demande pas de construire l'instance.

Quelqu'un a-t-il des idées?

Voici un exemple application

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Practices.Unity; 
using System.Reflection; 

namespace ConsoleApplication7 
{ 
    public interface IConstructorType1 { } 
    public interface IConstructorType2 { } 
    public interface INeedThisDependency { } 
    public class NeedThisDependency : INeedThisDependency { } 

    public class MyDomainObject 
    { 
     public MyDomainObject(IConstructorType1 constructorType1) { } 
     public MyDomainObject(IConstructorType2 constructorType2) { } 

     [Dependency] 
     public INeedThisDependency Needed { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      IUnityContainer unityContainer = new UnityContainer(); 
      unityContainer.RegisterType<INeedThisDependency, NeedThisDependency>(); 
      //Try with type 1 constructor 
      ConstructorInfo constructorInfo1 = typeof(MyDomainObject).GetConstructor(new Type[] { typeof(IConstructorType1) }); 
      MyDomainObject instance1 = CreateTheInstance(unityContainer, typeof(MyDomainObject), constructorInfo1, null); 
      //Try with type 2 constructor 
      ConstructorInfo constructorInfo2 = typeof(MyDomainObject).GetConstructor(new Type[] { typeof(IConstructorType2) }); 
      MyDomainObject instance2 = CreateTheInstance(unityContainer, typeof(MyDomainObject), constructorInfo2, null); 
     } 

     //This is the only point I have any influence over what happens 
     //So this is the only place I get to change the code. 
     static MyDomainObject CreateTheInstance(IUnityContainer unityContainer, Type type, ConstructorInfo constructorInfo, object parameters) 
     { 
      var result = (MyDomainObject)constructorInfo.Invoke(new object[] { parameters }); 
      //This will throw an ambiguous constructor exception, 
      //even though I am not asking it to construct anything 
      unityContainer.BuildUp(type, result); 
      //This will not build up dependencies 
      unityContainer.BuildUp(result); 
      if (result.Needed == null) 
       throw new NullReferenceException("Needed"); 
      return result; 
     } 
    } 
} 
+0

Un intercepteur est-il défini pour ce type? Cela pourrait causer un tel problème dans la méthode BuildUp! – Falcon

+0

Non, je n'ai pas d'intercepteurs ou rien du tout comme ça. –

Répondre

0

Au lieu d'appeler BuildUp, appelez cette aide CallInjectionMethod.

public static class UnityContainerHelper 
{ 
    public static void CallInjectionMethod(this IUnityContainer unityContainer, object instance, params ResolverOverride[] overrides) 
    { 
     if (instance == null) 
      throw new ArgumentNullException("Instance"); 

     var injectionMethodInfo = instance.GetType().GetMethods().Where(x => x.GetCustomAttributes(typeof(InjectionMethodAttribute), true).Any()).SingleOrDefault(); 
     if (injectionMethodInfo == null) 
      return; 
     var parameters = injectionMethodInfo.GetParameters(); 
     if (parameters.Length == 0) 
      return; 

     var dependencies = new object[parameters.Length]; 
     int index = 0; 
     foreach (Type parameterType in parameters.Select(x => x.ParameterType)) 
     { 
      dependencies[index] = unityContainer.Resolve(parameterType, overrides); 
      index++; 
     } 
     injectionMethodInfo.Invoke(instance, dependencies); 
    } 
} 
1

C'est un bogue dans BuildUp, malheureusement.

+0

Bonjour Chris. J'ai ajouté une méthode d'assistance pour appeler la méthode d'injection de l'objet. –