Simplifying PRISM’s EventAggregator

October 9, 2011

I recently started using PRISM’s EventAggregator for messaging in my WPF applications, however I find the syntax confusing, and hard to remember.

Here’s the default syntax for PRISM’s EventAggregator

// Optional: Create Event "Message"
// Needed for multiple parameters, but not for single parameter
// messages. I prefer using one in most cases because I find
// it makes it easier to read the code
public class TickerSymbolSelectedMessage
{
    public string StockSymbol { get; set; }
}

// Create an Event
public class TickerSymbolSelectedEvent : 
    CompositePresentationEvent<TickerSymbolSelectedMessage>{}

// Subscribe to an Event
eventAggregator.GetEvent<ChangeStockEvent>().Subscribe(ShowNews);

public void ShowNews(TickerSymbolSelectedMessage msg)
{
   // Handle Event
}

// Broadcast an Event
eventAggregator.GetEvent<ChangeStockEvent>().Publish(
    new TickerSymbolSelectedMessage{ StockSymbol = “STOCK0” });

There are a few things that irritate me about this syntax:

  • Needing to call GetEvent() all the time before subscribing/publishing
  • Needing a reference to the EventAggregator anywhere I want to use it
  • Needing to create two classes for an Event: the Event itself and the EventMessage (technically this one is optional if you only have one Parameter, but I like to create it anyways because I find it easier to read)

A large portion of the time I am working small apps which usually have a single purpose, so I wrote myself a simple helper class that gets rid of these annoyances. I’m not sure I’d recommend using this in larger apps since it passes all the events over the same channel, but I find it makes my life with small apps much simpler.

Now I just create the EventMessage, and can use some easy Subscribe/Publish calls anywhere in the application. Simple, easy to remember syntax, no need to pass around an EventAggregator object, and all I have to create is my Event Messages.

// Create the Event Message
public class TickerSymbolSelectedMessage
{
    public string StockSymbol { get; set; }
}

// Subscribe to Events
EventSystem.Subscribe<TickerSymbolSelectedMessage>(ShowNews);

public void ShowNews(TickerSymbolSelectedMessage msg)
{
   // Handle Event
}

// Broadcast Events
EventSystem.Publish<TickerSymbolSelectedMessage>(
    new TickerSymbolSelectedMessage{ StockSymbol = “STOCK0”});

And here’s the EventSystem class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Prism.Events;

namespace MyNamespace
{
    /// <summary>
    /// Static EventAggregator
    /// </summary>
    public static class EventSystem
    {
        private static IEventAggregator _current;
        public static IEventAggregator Current
        {
            get
            {
                return _current ?? (_current = new EventAggregator());
            }
        }

        private static CompositePresentationEvent<TEvent> GetEvent<TEvent>()
        {
            return Current.GetEvent<CompositePresentationEvent<TEvent>>();
        }

        public static void Publish<TEvent>()
        {
            Publish<TEvent>(default(TEvent));
        }

        public static void Publish<TEvent>(TEvent @event)
        {
            GetEvent<TEvent>().Publish(@event);
        }

        public static SubscriptionToken Subscribe<TEvent>(Action action, ThreadOption threadOption = ThreadOption.PublisherThread, bool keepSubscriberReferenceAlive = false)
        {
            return Subscribe<TEvent>(e => action(), threadOption, keepSubscriberReferenceAlive);
        }

        public static SubscriptionToken Subscribe<TEvent>(Action<TEvent> action, ThreadOption threadOption = ThreadOption.PublisherThread, bool keepSubscriberReferenceAlive = false, Predicate<TEvent> filter = null)
        {
            return GetEvent<TEvent>().Subscribe(action, threadOption, keepSubscriberReferenceAlive, filter);
        }

        public static void Unsubscribe<TEvent>(SubscriptionToken token)
        {
            GetEvent<TEvent>().Unsubscribe(token);
        }        public static void Unsubscribe<TEvent>(Action<TEvent> subscriber)
        {
            GetEvent<TEvent>().Unsubscribe(subscriber);
        }
    }
}