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

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

     // #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 с правильным типом.

Это ошибка? или я ошибся в настройках?


person Pratik    schedule 26.02.2016    source источник
comment
Это может быть не проблема StructureMap, а проблема с тем, как работает динамический вызов. Что произойдет, если вы используете отражение для вызова метода Handle? То есть явно найти метод на inst, который называется Handle и принимает параметр типа m.GetType().   -  person Yacoub Massad    schedule 26.02.2016
comment
@YacoubMassad: то же самое и с отражениями, я действительно вижу, что отраженный метод имеет метод дескриптора ThirldEvent. GetAllInstances возвращает неправильный объект из того, что я вижу в отражении   -  person Pratik    schedule 26.02.2016
comment
Есть ли причина, по которой вы реализуете интерфейсы явно, а не неявно? Попробуйте реализовать их неявно.   -  person Yacoub Massad    schedule 26.02.2016


Ответы (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 });
}
person Cobster    schedule 26.02.2016
comment
Спасибо за объяснение, в итоге я использовал вариант вашего кода для вызова метода дескриптора. Не могу действительно использовать явные методы, так как в каком-то устаревшем коде много изменений кода. - person Pratik; 29.02.2016