In my continuing (point-less) mission to avoid using anything related to MS Prism - a quick implementation of an EventAggregator using Rx - took about 5 minutes to write for a problem I currently have, normally try and avoid using such a pattern as it can lead the scattering of business logic which can hard to 'follow' when refactoring / re-visting code.
Trying to kepp the interace as simple and obvious as possible (symetric design) - this will be injected by the container:
public interface IEventAggregator : IDisposable | |
{ | |
void Publish<T>(T @event) where T : BaseEvent; | |
IObservable<T> Notify<T>() where T : BaseEvent; | |
IObservable<T> Notify<T>(IScheduler scheduler) where T : BaseEvent; | |
} |
Simple base event class, not thing special at the moment, might add a timestamp in the future, but more likely to do that with Rx on the event stream using the apply named Timestamp method:
public abstract class BaseEvent | |
{ | |
} |
Included a simplifed Schedulers wrapper - idea being you can get any of the Rx Schedulers in one place, and importantly makes unit testing easier:
public interface ISchedulers | |
{ | |
IScheduler Dispatcher { get; } | |
IScheduler TaskPool { get; } | |
} |
Show me the money...
public sealed class EventAggregator : IEventAggregator, IDisposable | |
{ | |
private readonly Subject<BaseEvent> _eventStream; | |
private readonly ISchedulers _schedulers; | |
public EventAggregator(ISchedulers schedulers) | |
{ | |
_schedulers = schedulers; | |
_eventStream = new Subject<BaseEvent>(); | |
} | |
public void Dispose() => _eventStream.Dispose(); | |
public void Publish<T>(T @event) where T : BaseEvent => _eventStream.OnNext(@event); | |
public IObservable<T> Notify<T>() where T : BaseEvent => Notify<T>(_schedulers.TaskPool); | |
public IObservable<T> Notify<T>(IScheduler scheduler) where T : BaseEvent => | |
_eventStream.OfType<T>() | |
.ObserveOn(scheduler); | |
} |
Comments
Post a Comment