One of the immensely awesome things that Udi Dahan has – if not invented, then at least brought to my attention – is the awesome “domain events – salvation” pattern.

If you’re familiar with the onion architecture, you’ve probably more than once experienced the feeling that you had the need to pull something from your IoC container some place deep in your domain model. In my experience, that often happens when you have a requirement on the form “when something happens bla bla, then some other thing must happen bla bla” where “something” and “some other thing” aren’t otherwise related.

An example could be when a new account (a.k.a. a customer that we mean to do business with) is registered in the system, we should make sure that our credit assessment of the account is fresh enough that we dare do the businesss.

I’ve found that the “domain events – salvation” provides a solution to that problem. Check this out:

“Whoa, what was that?” you might ask… that was a domain object that did some stuff, and in the end it raised a “domain event”, telling to the world what just happened. And yes, that was a domain object calling out to some static nastiness – but I promise you, it isn’t as nasty as you may think.

I’d like to assure you that the Account class is fully unit testable – i.e. it can be tested in isolation, just like we want. And that’s because we can abstract the actual handling of the domain events out behind an interface, IHandleDomainEvents, which is what actually gets to take care of the domain events – something like this:

and then IHandleDomainEvents can be implemented in several flavors and “injected” into the domain as a static dependency, e.g. this bad boy for testing:

which can be used by installing a new instance of it in the setup phase of each test, and then running assertions against the collected domain events in the assert phase.

The coolest part though, is the production implementation of IHandleDomainEvents – it may look like this:

thus delegating the handling of domain events to all implementors of ISubscribeTo<TDomainEvent>. This way, if I have registered this guy in my container:

I can kick off a new credit assessment workflow when a new account is registered, and everything is wired together in a way that is semantically true to the domain. Also, my domain object suddenly get to pull stuff from the container (albeit in an indirect fashion), without even knowing about it!

Domain events salvation example

3 thoughts on “Domain events salvation example

  • 13. December 2012 at 12:02
    Permalink

    Just to be clear, in the CastleWindsorDomainEventDispatcher wouldn’t you have to call container.ResolveAll<ISubscribeTo> in order to get all the subscribers of the specific domain event type, otherwise I think you would have to use dynamic dispatch by assigning domainEvent to a dynamic variable.

    Also what’s your opinion on making the DomainEvents.Current property internal and then use InternalsVisibleToAttribute in order to restrict the ability to change it to i.e. a unittest assembly. That way you don’t risk having production-code that changes the event handler by mistake or from lack of knowledge.

    Oh yeah btw some of the characters like are getting chunked up so the html-encode isn’t being processed. I think that the syntax highlighter is to blame.

  • Pingback: I let you know that something happened « Nexus#

Comments are closed.