Yea another simplification of Prism’s EventAggregator syntax

It’s been quite a while since I worked with Prism’s EventAggregator. Today however I need to use it. As soon as I started to write my code, I heard my friend Jeremy Miller in my head saying how much he hates the ceremony of  GetEvent<> pattern that Prism’s EA introduces. What he is talking about is code like the following

//publisher
public class OrderController {
  private IEventAggregator _ea;
  
  public OrderController(IEventAggregator ea) {
    _ea = ea;
  }

  public void SelectOrder(Order order) {
    _ea.GetEvent<OrderSelected>().Publish(order);
  }
}

//subscriber
public class OrderViewModel {
  public OrderViewModel(IEventAggregator ea) {
    ea.GetEvent<OrderSelected>().Subscribe(OnOrderSelected());
  }

  public void OnOrderSelected(Order o) {
  }
}

As you can see above, that each time I need to publish or subscribe, I am calling GetEvent<T>

I then found my way back to my buddy Ward’s post on the subject here: http://neverindoubtnet.blogspot.com/2009/07/simplify-prism-event-aggregator.html. In that post, Ward suggested that a way to deal with this was to create an event say OrderSelected which derives from CompositePresentationEvent<OrderSelected>and in so doing removes the need for a special payload class as the event is the payload. He then adds a set of extension methods directly to EA for handling Publish and Subscribe. Using my example above the code would now look like this with his extensions.

//publisher
public class OrderController {
  private IEventAggregator _ea;
  
  public OrderController(IEventAggregator ea) {
    _ea = ea;
  }

  public void SelectOrder(Order o) {
    _ea.Publish<OrderSelected>();
  }
}

//subscriber
public class OrderViewModel {
  private IEventAggregator _ea;
  
  public OrderViewModel(IEventAggregator ea) {
    ea.Subscribe<OrderSelected>(OnOrderSelected);
  }

  public void OnOrderSelected(Order o) {
  }
}

Which is much much cleaner. There’s no longer any need for calling GetEvent<T>(). However, there’s two parts about the approach that I just had a hard time digesting. I am not saying it is a bad approach but:

  • It requires the event class to inherit from CompositePresentationEvent<T> when I would prefer not having to carry any base class requirement.
  • It requires that the T that it inherits from is itself.

And so over a year later, I decided to take another crack at it with a slightly different approach. This one doesn’t require any base class so it removes the 2 constraints above. It basically uses extension methods to wrap / unwrap the passed in parameter with CompositePresentationEvent. It removes you from having to know about that event at all.

Rather than chop it up to make it fit the narly CodeBetter column constraints, go grab it at CodePaste here

Makes the code nice and clean. Now my event classes are just simple pocos. It also also maintains the nice syntax that Ward achieved in his pioneering approach that led me down this path.

Next step is we need an IoC autowireup facility for EventAggregator, that would make Jeremy very happy Smile

This entry was posted in EventAggregator, prism. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Anton

    Hi,

    Can you help me?
    I’m have code
    var viewRequestedEvent = eventAggregator.GetEvent();
    viewRequestedEvent.Subscribe(ViewRequestedEventHandler, ThreadOption.PublisherThread, true);

    public void ViewRequestedEventHandler(string moduleName){…}

    and i’m trying to use your extension, it’s look good, but when i subsribe on event

    eventAggregator.Subscribe(ViewRequestedEventHandler, ThreadOption.PublisherThread, true);

    i have error

    cannot convert from ‘method group’ to ‘System.Action

    what’s wrong?

  • http://codebetter.com/members/gblock/default.aspx Glenn Block

    Thanks Jakub, I have no idea what happened, but I fixed it now.

  • http://blog.gutek.pl/ Jakub Gutkowski

    Glenn, are you sure that code runs?

    public OrderViewModel(IEventAggregator ea) {
    _ea = ea;
    }
    public OrderViewModel() {
    _ea.Subscribe(OnOrderSelected);
    }

    maybe I’m missing something but it looks like you have 2 constructors which and _ea in parameters less one will be null.

  • http://paulomorgado.net/ Paulo Morgado

    I’ve been working on my own event broker: http://pmeventbroker.codeplex.com/

    It’s still a work in progress, but almost done.