Questions regarding EventAggregator

Topics: Prism v4 - Silverlight 4
Nov 23, 2010 at 3:52 PM

I need some advice on using the EventAggregator.  Currently, I just want to use the EventAggregator and not other aspects of Prism.  I am also using MEF, not Unity.

 

Everything I have researched says to use a single instance of the EventAggregator.  All those examples seem to use Prism and Unity to take care of that so I would like an example on doing it with MEF.

I also want to know a little more about waht goes on under the hood of the EventAggregator.  My concern is whether I need multiple instances of it or not and the best way to handle accomplishing that.  The situation is that I have different views and viewmodels that are similar in nature and may publish the same event.  Does the EventAggregator differentatiate events depending on the object that published it?  For example, if class A publishes MyEvent and class B also publishes MyEvent will subscribers to MyEvent get the evnt from both class A and class B?  If so, I need to avoid this situation.  Should I just use a filter or use a different EventAggregator for separate components within my application.

Since this is important, let me explain further using specifics from my application.  The main portion of my application is a graph control.  This user control visualizes data in the form of Node objects.  Node objects can be connected to other nodes via Edges (lines).  The view model for the graph control will be publishing a serieis of events such as NodeMouseEnter, NodeMouseLeave, NodeMouseClick, etc.  Certain portions of the user interface will subscribe to these events.  An example is a popup control that displays information about a node when the mouse hovers over it.  Now, the flip side is that some portions of the application have there own version of the graph control (with their own viewmodel).  Much of the functionality will be the same and they will share base classes.  They would also publish many of the same events but the subscribers must be different.  If I hover my mouse cursor over a node in a subgraph (not the main graph) I want the node popup to show on the subgraph, not on the main graph (and vice versa).  Does this mean I want a separate EventAggregator to handle these different Graph controls??

Thanks,

Todd

Developer
Nov 23, 2010 at 6:30 PM
Edited Nov 23, 2010 at 6:31 PM

Hi Todd,

In order to support using the Event Aggregator with MEF, the Prism Library provides a MefEventAggregator class (located in the Prism.MefExtensions.Silverlight project), which "Exports the EventAggregator using the Managed Extensibility Framework (MEF)". So if you want to use it, you should import an instance of IEventAggregator, providing that you have added the necessary composable part to the Aggregate Catalog (which is done by the MefBootstrapper). You could find an example of using the Event Aggregator in the Stock Trader Reference Implementation.

If you don't want to add the entire Prism libraries that hold the EventAggregator, the MefEventAggregator and even the MefBootstrapper itself, you could put the necessary classes for the EventAggregator (which are located in the Events folder of the Prism.Silverlight project) in a library of yours, and export the EventAggregator class as an IEventAggregator. To this purpose, you might also find this blog post by Damian Schenkelman useful. Even though it is targeted at an older Prism version, it should still work, as there aren't breaking changes in Event Aggregation in Prism v4.0.

As for your specific scenario, you could make use of the Subscription Filtering feature of the Event Aggregator, to make the subscribers handle events only if a certain condition is met (which would suit to your scenario, in my understanding). You can read about it in this article from the Prism documentation (Under the Event Aggregation section, and specifically under the Subscription Filtering sub section).

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Nov 23, 2010 at 9:28 PM

Thanks Guido.

I decided, for now, to not use MEF for this situation.  I am using MEF in other areas but do to the timeline I am on I wanted to go with a slightly different scenario.  I have plans, in the future, to update my solution to use the MefBootStrapper but I don't have that time for now.  I ended up wrapping the EventAggregator and providing a static property to access an instance of the class.

I don't need the filters at this point but hope they will end up allowing me to separate the events of different components.  That is an important aspect that I will need in the near future.  I just came across a perfect example.  My Node class is now pbulishing a NodeMouseEnterEvent whenever the mouse enters it.  The trick here is that more than one graph may contain Node objects and the events shouldn't cross components.  I.E., Graph A should not get events from nodes that are on Graph B.  I can use a Filter for this but I am trying to ensure that this is the best option.  Each graph could have hundreds of nodes and the mouse enter and leave events could fire very quickly

Developer
Nov 24, 2010 at 1:56 PM

It's nice to see that you're planning to implement further Prism capabilities.

As regarding your concern with the Event Aggregator, considering that you're going to have several instances of the Node objects, it could be a better idea to have a separate instance of the Event Aggregator for each Graph object, so as to avoid possible performance issues.

Take into account that the Event Aggregator is useful to communicate between loosely coupled components. If the communication will be between components that are located in the same assembly, it isn't necessary to use the Event Aggregator; you could just use plain .NET events.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Nov 24, 2010 at 2:57 PM

Thanks Guido.

I have taken in to account the EventAggregator being useful for communication between loosely coupled components.  Currently, most of my components are in the same assembly but they are very loosely coupled.  I am also leaning towwards splitting my main project into multiple projects because it is getting rather large and unrulely.

I weighed the decision to use EventAggregator for some time.  I finally made the decision with the current task I am working on.  I have a control I created that is a popup and shows information for a node.  The control itself has no reference to a node.  The graph control (which has the popup control and the nodes) would have to refire the node mouse enter and mouse leave events and I would have had to make my popup control have reference to the graph view model (since I am using MVVM).  I didn't want this tight coupling so the EventAggregator is a perfect fit.

Since I created a wrapper for the EventAggregator, I should be able to easily update it to allow overriding the default instance (to provide additional instances for additional graphs).  This appears to be similar to how the Messenger API works in the MVVM Light Framework.

Todd