Подписаться на события 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
Добавьте EventAggregator.GetEvent(Type eventType), чтобы получить событие без общих параметров.
Создайте выражение типа Action, используя отражение
Подпишитесь на событие, используя отражение (т.е. вызывая метод Subscribe) и передавая Expression.Compile в качестве параметра.
Это работает, если KeepAlive имеет значение true.