Structuremap возвращает неправильный экземпляр для открытого универсального типа?

Я пытаюсь использовать Structuremap с открытым универсальным, чтобы получить экземпляры обработчика событий во время выполнения, я использую конфигурацию открытого универсального

     // #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)
            {

            }

        }

Мой код работает в тех случаях, когда я запрашиваю зависимость через внедрение в конструктор, как это работает нормально.

public MyClass(IHandle<MyEvent>[] alleventHandlers)
{

}

Однако в одном из моих случаев мне нужно получить зависимость во время выполнения. Ниже приведен код, который я использую

 // 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)

 }

Я получаю следующую ошибку. {"Наилучшее перегруженное соответствие метода для 'MyNameSpace.EventHandlerClass.Handle(MyNameSpace.Events.ThirdEvent)' имеет недопустимые аргументы"}

GetAllInstances каким-то образом возвращают объект EventHandlerClass с методом Handle, ожидающим событие ThirdEvent, хотя я вызывал GetAllInstances с правильным типом.

Это ошибка? или я сделал ошибку в конфигурации?

1 ответ

Решение

Динамическая переменная имеет доступ только к методам типа (обычно общедоступным, но основывается на контексте). Он не имеет доступа к интерфейсным методам, которые реализованы явно. Единственный способ вызвать явные реализации интерфейса - привести объект к интерфейсу.

Таким образом, у вас есть два варианта: а) реализовать интерфейсы неявно, как предложено @Yacoub, или б) использовать рефлексию для вызова метода.

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 });
}
Другие вопросы по тегам