2016-02-26 4 views
1

Je suis en train d'utiliser StructureMap avec générique ouvert pour obtenir des instances d'un gestionnaire d'événements au moment de l'exécution, je suis en utilisant une configuration générique ouverteStructuremap renvoyant une mauvaise instance pour un type générique ouvert?

 // #1 Configuration 
     scan.ConnectImplementationsToTypesClosing(typeof(IHandle<>)); 
// #2 Actual class 
     public class EventHandlerClass : 
      IHandle<MyEvent>, 
      IHandle<AnotherEvent>, 
      IHandle<ThirdEvent>, 
     { 
      void IHandle<MyEvent>.Handle(MyEvent args) 
      { 

      } 
      void IHandle<AnotherEvent>.Handle(AnotherEvent args) 
      { 

      } 
      void IHandle<ThirdEvent>.Handle(ThirdEvent args) 
      { 

      } 

     } 

Mon code fonctionne pour les cas où je demande la depdendency par injection constructeur comme Cela fonctionne bien. Cependant, dans l'un de mes cas, j'ai besoin de récupérer la dépendance au moment de l'exécution. Ci-dessous le code que je utilise

// Code 
Type t = typeof(IHandle<>); 
MyEvent m = new MyEvent(); 
var generic = t.MakeGenericType(m.GetType()); 
dynamic instances = nestedContainer.GetAllInstances(genType) as IEnumerable; 

foreach(dynamic inst in instances) 
{ 
    inst.Handle(m) 

} 

Je reçois l'erreur suivante. { « Le match de la meilleure méthode surchargée pour « MyNameSpace.EventHandlerClass.Handle (MyNameSpace.Events.ThirdEvent) » a des arguments non valides »}

GetAllInstances semble en quelque sorte à retourner un objet de EventHandlerClass avec une méthode de poignée attendant ThirdEvent événement bien J'ai appelé GetAllInstances avec le type correct.

Est-ce un bug? ou ai-je fait une erreur dans la configuration?

+0

Cela peut ne pas être un problème de StructureMap mais un problème avec le fonctionnement de l'appel dynamique. Que se passe-t-il si vous utilisez la réflexion pour invoquer la méthode 'Handle'? Par exemple, recherchez explicitement la méthode sur 'inst' nommée' Handle' et prenez un paramètre de type 'm.GetType()'. –

+0

@YacoubMassad: c'est la même chose avec des réflexions aussi, je peux réellement voir la méthode reflétée ayant la méthode de poignée de ThirldEvent. Le GetAllInstances renvoie le mauvais objet de ce que je vois dans la réflexion – Pratik

+0

Y a-t-il une raison pour laquelle vous implémentez les interfaces explicitement et non implicitement? Essayez de les implémenter implicitement. –

Répondre

0

La variable dynamique a uniquement accès aux méthodes de type (généralement public, mais est basé sur le contexte). Il n'a pas accès aux méthodes d'interface explicitement implémentées. La seule façon d'invoquer des implémentations d'interface explicites consiste à convertir l'objet en interface.

Vous avez donc deux options, soit a) implémenter implicitement les interfaces comme suggéré par @Yacoub, soit b) utiliser la réflexion pour invoquer la méthode.

foreach(dynamic inst in instances) 
{ 
    Type type = inst.GetType(); 
    Type interfaceType = type.GetInterfaces().Single(t => t == generic); 
    interfaceType.GetMethod("Handle").Invoke(inst, new object[] { m }); 
} 
+0

Merci pour l'explication, j'ai fini par utiliser une variation de votre code pour invoquer la méthode handle. Cant vraiment utiliser les méthodes explicites comme son beaucoup de changement de code dans un code hérité. – Pratik