How to use Prism EventAggregator for .NET app development

by: | Apr 6, 2020

In my previous article, I covered why to use Prism EventAggregator for .NET app development, the Publisher-Subscriber pattern, and the scenarios in which to use it. Now it’s time to show exactly how to use it with some code!

Installation?

Well, there isn’t any! The EventAggregator is part of Prism.Core, so if you’re already using Prism in your project, the EventAggregator is ready and waiting for you.

Inject it into the constructor

EventAggregator implements the interface IEventAggregator. To use it in any class (that’s registered with Prism’s IoC), all you need to do is ask for an instance of IEventAggregator in the constructor.

public MyViewModel(IEventAggregator eventAggregator)
{
  _eventAggregator = eventAggregator;
}

Prism will automatically pass an instance of its EventAggregator when the ViewModel is constructed. There’s no need to register or set up anything else.

Create an event

Next, we need something to send: an event. There are two types of events: events WITHOUT a parameter and events WITH a parameter. To create an event without a parameter, we create a regular new class and have it inherit from PubSubEvent.

public class MyEvent : PubSubEvent
{
}

If we want to pass a parameter, we inherit from the generic PubSubEvent<T> where T is the type of the parameter we want to pass. This can be a primitive type or a complex object.

public class MyParameterEvent : PubSubEvent<MyParameter>
{
}

Subscribe to an event

Now that we have our EventAggregator and our event, it’s time to subscribe to it. First, we need to call GetEvent<TEvent>() on our EventAggregator, which will return an instance of our event. Then we call Subscribe(…) on the event passing in the method or Action that will handle our event.

public class MySubscriberViewModel
{
  public MySubscriberViewModel(IEventAggregator eventAggregator)
  {  
    eventAggregator
      .GetEvent<MyEvent>()
      .Subscribe(HandleMyEvent);
  }

  private void HandleMyEvent()
  {
    // Do some stuff here
  }
}

It’s similar for handling events with parameter:

public class MySubscriberViewModel
{
  public MySubscriberViewModel(IEventAggregator eventAggregator)
  {
    _eventAggregator
      .GetEvent<MyParameterEvent>()
      .Subscribe(HandleMyParameterEvent);
  }
  private void HandleMyEvent(MyParameter parameter)
  {
    // Do some stuff with the parameter here
  }
}

Publish an event

Now that our events will be handled, all that’s left is to publish them. To do this, we again have to call GetEvent<TEvent>() to create an instance of the event we want to publish. This time we’ll call Publish(…).

public class MyPublisherViewModel
{
  private readonly IEventAggregator _eventAggregator;

  public MyPublisherViewModel(IEventAggregator eventAggregator)
  {
    _eventAggregator = eventAggregator;
  }

  private void PublishEvent()
  {
    _eventAggregator
      .GetEvent<MyEvent>()
      .Publish();
  }
}

Or, pass a parameter:

public class MyPublisherViewModel
{
  private readonly IEventAggregator _eventAggregator;

  public MyPublisherViewModel(IEventAggregator eventAggregator)
  {
    _eventAggregator = eventAggregator;
  }

  private void PublishParameterEvent()
  {
    _eventAggregator
      .GetEvent<MyParameterEvent>()
      .Publish(new MyParameter());
  }
}

Unsubscribe from an event

Finally, if you want to stop listening to an event, you can unsubscribe from it easily with the Unsubscribe() method:

_eventAggregator
  .GetEvent<MyEvent>()
  .Unsubscribe(HandleMyEvent);

Advanced stuff

Everything described until now should be enough to cover 95% of cases. However, if you want some more control, EventAggregator has you covered. Namely, the Subscribe() method has a few optional parameters that we can use to configure EventAggregator’s behavior:

  • threadOption: An enum that specifies on which thread the event will be handled. It has three values: PublisherThread (default), UIThread and BackgroundThread.
  • keepSubscriberReferenceAlive: A bool that’s false by default. Set this to true if you want the EventAggregator to keep a reference of a subscriber, even if it has no other references, which prevents it from being garbage collected. (This will make it behave in a similar way as Xamarin.MessagingCenter does.)
  • filter: A filter in the form of a lambda expression returning a bool that evaluates whether or not the subscriber should receive the event. (This is only applicable for events that have a parameter.)

Here you can see them all in action:

_eventAggregator
  .GetEvent<MyParameterEvent>()
  .Subscribe(
    HandleMyEvent,              // Call this when the event is received
    ThreadOption.UIThread,      // Call HandleMyEvent on the UI thread
    true,                       // Keep a strong reference to this class
    value => value == "valid"); // Only call HandleMyEvent when this condition is met

Next up: EventAggregator unit tests

As you can see, EventAggregator is a powerful tool that’s easy to use. If you want a complete working example, check out the repository here.

In the next article, I’ll cover writing unit tests that include the EventAggregator. Make sure to follow us on Facebook, Twitter, and LinkedIn to be notified about the next post!