igloocoder.com Wiki

Edit

Sample

Edit

The aggregator

The main component in the Event Aggregator is the aggregator itself. It's likely that you will want only one instance of the EventAggregator class during the life of your application. The EventAggregator is not designed to be a singleton. Instead it is expected that you will serve it up in a singleton manner either through your IoC container or other methods. The EventAggregator class implements the IEventAggregator interface which can be used to populate an IoC container.

The EventAggregator class (and IEventAggregator interface) implement three main methods for your use.

Edit

Register

The Register method allows you to register objects with the event aggregator so that they will receive messages that they are configured to handle. The Register method prevents an instance of an object from being registered more than once with the aggregator.

Registration of objects can be a tedious and repetitive code task. As a result, it can be handled nicely by using a combination of Aspect Oriented Programming and conventions. More to come...

Edit

Unregister

Once an object has been registered with the aggregator, it will need to be unregistered when it's lifecycle has ended. To do this, simply call the Unregister method on the EventAggregator passing it the object you wish to remove. If you request an object be unregistered and it currently is not registered with the aggregator, nothing will occur.

Like registration of objects, unregistering can be a very repetitive code task and a candidate for Aspect Oriented Programming and conventions. More to come...

Edit

Raise

The final piece to the EventAggregator is the ability to raise messages/events. There are a number of methods on the EventAggregator providing this functionality. When a message is raised using one of these methods, the aggregator will dispatch it to the appropriate registered objects.

Edit

Raising events

Raising events requires a call to one of the EventAggregator.Raise methods. Traditional events required an implementation of EventArgs as part of their call. With the EventAggregator you send a message when raising the event. The message can take one of two forms. It can either be an instance of a class or it can be defined as an interface.

Edit

Classes for messages

When using a class for the message you simply pass the instance of that class that you have created as a parameter to the Raise method.

eventAggregator.Raise(new MyMessage());

Often you will want to send data to the handler of the event. To do this you just need to create a message type that has properties on it.

public class MyMessage
{
public string Value1 {get;set;}
public string Value2 {get;set;}

public MyMessage(string value1, string value2)
{
Value1 = value1;
Value2 = value2;
}
}


...

eventAggregator.Raise(new MyMessage("foo", "bar");

Edit

Interfaces for messages

Another method for sending messages is to use interfaces. When raising an event, a Raise method on the event aggregator is still called. The method is generic and the type used is that of the interface defining your message. If the message requires data content that is provided through a method parameter of type Action where T is the message type.

eventAggregator.Raise
(m=>
{
m.Value1="foo";
m.Value2="bar";
}
);

If the event you want to raise requires no data to be sent to the handler, then there is no need to make use of the Action parameter.

event.Aggregator.Raise();

When using an interface to define your message, EventAggregator makes use of DynamicProxy to create a temporary in memory instance of a class implementing that interface. That class instance is then populated using the Action that you can optionally provide to as a parameter to the Raise method. The life of the temporary in memory class is limited to the time it takes EventAggregator to pass the message to all registered listeners handling that interface type.

Edit

Handling messages

Objects that register to receive messages need to implement the IHandleMessagesOfType<T> interface. The <T> on the generic interface is used to indicate the message type that is being handled.

The IHandleMessagesOfType<T> interface defines one method;
public interface IHandleMessagesOfType<T>
{
void Handle(T message)
}

When implemented the class handling a specific message type will look like this.

public class SomeReceivingClass : IHandleMessagesOfType<IMyMessage>
{
public void Handle(IMyMessage message)
{
//do work in here
}
}

Because we are only implementing interfaces on a class, it is possible, and often necessary, for us to have a listening class handle many different message types. To accomplish this you simply need to implement the IHandleMessagesOfType<T> interface; each with a different message type for T.

public class SomeReceivingClass : IHandleMessagesOfType<IMyMessage>, IHandleMessagesOfType<IAnotherMessage>
{
public void Handle(IMyMessage message)
{
//do work in here
}

public void Handle(IAnotherMessage message)
{
//do work in here
}
}

Edit

Polymorphic Dispatch

ScrewTurn Wiki version 2.0.27. Some of the icons created by FamFamFam.