Question

I want to subscribe to an EventAggregator event using Reflection, because I am trying to dynamically wire up event subscriptions between Prism modules at runtime. (I'm using Silverlight 5, Prism and MEF).

What I want to achieve is calling _eventAggregator.GetEvent<MyType>().Subscribe(MyAction) in one of my modules, but I am stuck at calling _eventAggregator.GetEvent<MyType>(). How can I proceed from there to call Subscribe(MyAction)?

Say my Event class is public class TestEvent : CompositePresentationEvent<string> { }. I don't know this at compile time, but I know the Type at runtime.

Here is what I have got so far:

 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>();

I would really appreciate a pointer in the right direction.

Was it helpful?

Solution

You can do this without having to worry about the "type" of event you are invoking by using dynamics.

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)
{
}

Now you really never need to know what the "event type" is.

OTHER TIPS

Could it be as simple as:

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

Assuming you know the payload type.

Personally, I see the aggregated events that are consumed outside of a module as this module's API and I try to place them in some sort of a shared assembly that other modules can compile against.

I found the answer for the case that the payload type is unknown here:

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

  1. Add EventAggregator.GetEvent(Type eventType) to get the event without generic parameters

  2. Build an expression of type Action using reflection

  3. Subscribe to event using reflection (i.e. calling Subscribe method) and passing Expression.Compile as the parameter.

This works if KeepAlive is true.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top