Messaging System in WPF

In WPF MVVM we might want to send a message from one View Model to another. For example, if we want to close a window and return data to the opener window. To allow such data exchange we can use a messaging system.

For that we have the EventAggregator pattern.

The EventAggregator class will store all the instances that are being tracked. So when a message is published all those listed instances will be notified.

  1. public interface IListen { }    
  2. public interface IListen<T> : IListen    
  3. {    
  4.     void Handle(T obj);    
  5. }    
  6.      
  7. public class EventAggregator    
  8. {    
  9.     private List<IListen> subscribers = new List<IListen>();    
  10.      
  11.     public void Subscribe(IListen model)    
  12.     {    
  13.         this.subscribers.Add(model);    
  14.     }    
  15.      
  16.     public void Unsubscribe(IListen model)    
  17.     {    
  18.         this.subscribers.Remove(model);    
  19.     }    
  20.      
  21.     public void Publish<T>(T message)    
  22.     {    
  23.         foreach (var item in this.subscribers.OfType<IListen<T>>())    
  24.         {    
  25.             item.Handle(message);    
  26.         }    
  27.     }    
  28. }  
To demonstrate this example let's use a class Car that will listen for signals and a class Guard that will notify the cars using a SignalMessage class.
  1. public class Car : IListen<SignalMessage>    
  2. {    
  3.     public Car(EventAggregator eventAggregator)    
  4.     {    
  5.         eventAggregator.Subscribe(this);    
  6.     }    
  7.      
  8.     public void Handle(SignalMessage obj)    
  9.     {    
  10.         Console.WriteLine("I'm a car and a guard is telling me to stop!");    
  11.     }    
  12. }    
  13.      
  14. public class Guard    
  15. {    
  16.     private EventAggregator eventAggregator;    
  17.      
  18.     public Guard(EventAggregator eventAggregator)    
  19.     {    
  20.         this.eventAggregator = eventAggregator;    
  21.     }    
  22.      
  23.     public void SignalCars()    
  24.     {    
  25.         this.eventAggregator.Publish(new SignalMessage { Message = "Stop" });    
  26.     }    
  27. }    
  28.      
  29. public class SignalMessage    
  30. {    
  31.     public string Message { getset; }    
  32. }   
Run this application.
  1. static void Main(string[] args)    
  2. {    
  3.     var eventAggregator = new EventAggregator();    
  4.      
  5.     var car1 = new Car(eventAggregator);    
  6.     var car2 = new Car(eventAggregator);    
  7.     var car3 = new Car(eventAggregator);    
  8.      
  9.     var guard = new Guard(eventAggregator);    
  10.      
  11.     guard.SignalCars();    
  12.      
  13.     Console.ReadKey(true);    
  14. }   
We will see that all the cards are being notified:

output