Limit your abstractionsApplication Events–event processing and RX
In my last post, I mentioned that this is actually an event processing system, so we might as well use actual event processing and see what we can gain out of this. I chose to use RX (reactive extensions), which can turn a series of events into a linq statement. This is incredibly powerful, and has some interesting implications when you combine this with your architecture. In particular, let us see what we can get when we set out to replace this with RX based event processing style.
We can get to something like this very easily:
public class CargoProcessor : EventsProcessor { public CargoProcessor() { On<Cargo>(cargos => from cargo in cargos where cargo.Delivery.Misdirected select MisdirectedCargo(cargo) ); On<Cargo>(cargos => from cargo in cargos where cargo.Delivery.UnloadedAtDestination select CaroArrived(cargo) ); } private object CaroArrived(Cargo cargo) { // handle event return null; } private object MisdirectedCargo(Cargo cargo) { // handle event return null; } }
We use RX to handle the linq processing over the events, and in EventsProcessor we have very little code, probably just:
public class EventsProcessor { private readonly List<Func<IObservable<object>, IObservable<object>>> actions = new List<Func<IObservable<object>, IObservable<object>>>(); protected void On<T>(Func<IObservable<T>, IObservable<object>> action) { actions.Add(observable => action(observable.OfType<T>())); } public void Execute(IObservable<object> observable) { foreach (var action in actions) { action(observable).Subscribe(); } } }
Elsewhere in the code we setup the actual Obsersable that we pass to all the EventsProcessors. The major advantages that we have with this style is that we have a natural syntax to do selection on the events that interest us, including fairly complex one. We still have easy time of creating new EventsProcessors if we want, but because the code for defining the selection is so compact, we can usually put related stuff together, which is going to be very helpful for making sure that the codebase is readable.
And, naturally, this method extends itself to handling events of multiple types in the same place. For example, if we want to also handle the HandlingEvent, we can do it in place, because it is very much related to the Cargo, it seems.
More posts in "Limit your abstractions" series:
- (22 Feb 2012) And how do you handle testing?
- (21 Feb 2012) The key is in the infrastructure…
- (20 Feb 2012) Refactoring toward reduced abstractions
- (16 Feb 2012) So what is the whole big deal about?
- (15 Feb 2012) All cookies looks the same to the cookie cutter
- (14 Feb 2012) Commands vs. Tasks, did you forget the workflow?
- (13 Feb 2012) You only get six to a dozen in the entire app
- (10 Feb 2012) Application Events–event processing and RX
- (09 Feb 2012) Application Events–Proposed Solution #2–Cohesion
- (07 Feb 2012) Application Events–Proposed Solution #1
- (06 Feb 2012) Application Events–what about change?
- (03 Feb 2012) Application Events–the wrong way
- (02 Feb 2012) Analyzing a DDD application

Comments
Comment preview