Подписаться на события Prism EventAggregator с отражением

Я хочу подписаться на событие EventAggregator с помощью Reflection, потому что я пытаюсь динамически подключать подписки на события между модулями Prism во время выполнения. (Я использую Silverlight 5, Prism и MEF).

То, чего я хочу достичь, это звонить _eventAggregator.GetEvent<MyType>().Subscribe(MyAction) в одном из моих модулей, но я застрял при вызове _eventAggregator.GetEvent<MyType>(), Как я могу перейти оттуда, чтобы позвонить Subscribe(MyAction)?

Скажи, что мой класс Event public class TestEvent : CompositePresentationEvent<string> { }, Я не знаю этого во время компиляции, но я знаю Type во время выполнения.

Вот что я получил до сих пор:

 Type myType = assembly.GetType(typeName); //get the type from string

 MethodInfo method = typeof(IEventAggregator).GetMethod("GetEvent");
 MethodInfo generic = method.MakeGenericMethod(myType);//get the EventAggregator.GetEvent<myType>() method

 generic.Invoke(_eventAggregator, null);//invoke _eventAggregator.GetEvent<myType>();

Я был бы очень признателен за указатель в правильном направлении.

3 ответа

Решение

Вы можете сделать это, не беспокоясь о "типе" события, которое вы вызываете, используя динамику.

Type eventType = assembly.GetType(typeName);
MethodInfo method = typeof(IEventAggregator).GetMethod("GetEvent");
MethodInfo generic = method.MakeGenericMethod(eventType);
dynamic subscribeEvent = generic.Invoke(this.eventAggregator, null);

if(subscribeEvent != null)
{
    subscribeEvent.Subscribe(new Action<object>(GenericEventHandler));
}

//.... Somewhere else in the class

private void GenericEventHandler(object t)
{
}

Теперь вам действительно не нужно знать, что такое "тип события".

Может ли это быть так просто, как:

var myEvent = generic.Invoke(eventAggregator, null) as CompositePresentationEvent<string>;
if (myEvent != null) 
    myEvent.Subscribe(MyAction);

Предполагая, что вы знаете тип полезной нагрузки.

Лично я вижу агрегированные события, которые потребляются за пределами модуля, как API этого модуля, и я пытаюсь поместить их в какую-то общую сборку, с которой могут компилироваться другие модули.

Я нашел ответ для случая, что тип полезной нагрузки неизвестен здесь:

http://compositewpf.codeplex.com/workitem/6244

  1. Добавьте EventAggregator.GetEvent(Type eventType), чтобы получить событие без общих параметров.

  2. Создайте выражение типа Action, используя отражение

  3. Подпишитесь на событие, используя отражение (т.е. вызывая метод Subscribe) и передавая Expression.Compile в качестве параметра.

Это работает, если KeepAlive имеет значение true.

Другие вопросы по тегам