Domain events salvation example

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!

Thoughts on how to integrate with 3rd party libraries when you’re a library author

Yoda in a Santa's costume, carrying a magic wandWhen building .NET systems for clients, it’s just awesome how much free open source that’s available at your fingertips – and with tools like NuGet around, it’s become extremely easy to rapidly pull in various colors and sizes of Legos to snap together and build on. Except, sometimes those Legos don’t snap 🙁

Different types of libraries and frameworks are more or less susceptible to Lego-snap-issues, depending on their place in the stack. That is, libraries with many incoming references are inherently problematic in this regard, the ubiquitous examples being logging libraries and serialization libraries.

When I built Rebus, one of my solemn goals was to make Rebus dependent on .NET BCL ONLY. All kinds of integration with 3rd party libraries would have to be made via small dedicated adapter projects, because this way – in the case where there’s a conflict with one of your own dependencies – only that single adapter would have to be either built against your version of the problematatic dependency, or switched for something else.

Serialization with Rebus

Rebus serializes message bodies by using an ISerializeMessages abstraction. And since Rebus’ default transport message serialization format is JSON, and I didn’t feel like re-re-re-inventing any wheels, I decided to pull in the nifty JSON.NET package in order to implement Rebus’ JsonMessageSerializer that is part of the core Rebus.dll. But that clearly violates Rebus’ goal of having no dependencies besides what’s in the .NET framework – so how did I solve that?

Simple: ILmerge JSON.NET into Rebus! Simple solution, very effective.

Maybe there’s something I’m being ignorant about here, but I don’t get why projects like e.g. RavenDB keeps having issues with their JSON.NET dependency. Why didn’t Ayende just merge it from the start?

Update January 7th 2013: Well, it appears that they did just that for RavenDB 2: RavenDB-220

Logging with Rebus

And then there’s logging – in order to log things good, all Rebus classes must be given access to a logger – and I like it when the logger is named after the classes it is being used from, which always turns out to be a piece of really useful information when you’re trying to track down where stuff went wrong some time in the past.

Ideally, I wanted a syntax that resembles the Log4Net one-liner, that you’ll most likely encounter if you come across code that uses Log4Net for logging – each class usually initializes its own logger like this:

thus retrieving a static readonly logger instance named after the calling class. So, originally I started out by copying the Log4Net API, providing adapters for console logging, Log4Net logging, etc.

That worked perfectly for a while, but later on, since I spent so much time writing integration tests for Rebus, I also wanted the logging mechanism to be swappable at runtime – i.e. I wanted it so that Rebus could have its logger swapped from e.g. a ConsoleLogger to a NullLogger in a performance test, where all the console output would otherwise interfere with the measurements.

Therefore, my logging “abstraction” is a bit more involved. But it accomplishes all goals: All classes can have a static logger instance, named after the class, swappable at runtime, without introducting dependencies on external stuff, and with very little (read: an acceptable amount of) ceremony (too much for my tastes actually, but I accept this one because of the goodness it brings).

Check out what a class must do in order to get a Rebus logger:

As you can see, the logger is set when the Changed event is raised – and by taking control of the add/remove operations of the event, I can ensure that the logger is set when each subscriber first subscribes. This way, the logger is immediately initialized by the currently configured static IRebusLoggingFactory, and in the event that the factory is changed, all logger instances are changed.

The Changed event is implemented like this:

The last thing is to provide a meaningful name to the logger – i.e. I wanted the name of the calling class to be used, so the call to GetCurrentClassLogger() had to do some StackFrame trickery in order to fullfil the promise made by its title. The implementation is pretty simple:

As you can see, it just skips one level on the call stack, i.e. it gets the calling method, and then we can use the standard reflection API to get the type that has this method. Easy peasy!

This was an example on how two of the more troublesome dependencies can be dealt with, allowing your library or framework to be effectively dependency-free.