Event Aggregator; subscriptors

In a previous article I talked about an event publisher based on Reactive Extensions, and I wrote some examples of subscriptors based on IObservable.

I will talk about two different kind of subscriptors or observers in this post.

I am using this pattern in my presenters (user interface), so I will start this post with a simple example of use case.

The first interface is the “Albums Browser”:

myImage

And the second interface is the “Album Editor”:

myImage (1)

 

So, I have two concerns in this scenario:

  • I want to update the Browser when the user saves a change on an album.
  • I want to open the edit use case when the user press the button Edit. But I don’t want a hard reference to the Edit Album Presenter or window, in the browser.

So, I will declare two events:

public class AlbumUpdated
{
    public AlbumUpdated(int id)
    {    
        AlbumId = id;
    }

    //Poid of the album
    private object AlbumId{get; private set;}
}


public class AlbumEditRequest
{
    public AlbumUpdated(int id)
    {    
        AlbumId = id;
    }

    //Poid of the album
    private object AlbumId{get; private set;}
}

The command to raise the event is the same in both cases:

EventAggregator.Publish(new AlbumUpdated(id));

EventAggregator.Publish(new AlbumEditRequest(SelectedAlbum.Id));

But we need two kind of subscription mechanism.

Instance Subscription

The observers for AlbumUpdated are live object instances watching the event. So the browser for that matter look like this:

public class AlbumBrowserPresenter
{
    public AlbumBrowserPresenter(
        EventAggregator eventAggregator)
    {
        eventAggregator.GetEvent<AlbumUpdated>()
                    .Subscribe(ReloadGrid);
    }
    
    private void ReloadGrid()
    {
        //do the reload here.
    }   
}

And you can subscribe to this same event in other use cases, for instance when you have a selector for Albums.

Type Subscription

The observer of AlbumEditRequest is a type, this means that the handler of this event is not a live object. The event aggregator implementation “create” an instance of all types implementing the interface and then call an specific method. The edit presenter looks like this:

public class AlbumEditPresenter
  : IHandler<AlbumEditRequest>
{
    public void Handle(AlbumEditRequest @event)
    {
        InitWithId(@event.AlbumId);
    }

    //...
}

The easy way to handle this scenario in the event aggregator is something like this:

public void Publish<TEvent>(TEvent @event)
{
    object subject;

    if (subjects.TryGetValue(typeof(TEvent), out subject))
    {
        ((ISubject<TEvent>)subject)
            .OnNext(sampleEvent);
    }

    ServiceLocator.Current
                .GetAllInstances<IHandler<TEvent>>()
                .ForEach(h => h.Handle(@event));
}

This same code is used in many places and examples for Domain Events, but we use it here with other purpose.


blog comments powered by Disqus
  • Categories

  • Archives