Implementing Domainevents in your application

Yngve Bakken Nilsen

Disclaimer: This is not some invention by me. The code I'm presenting is written by me, but inspired by the work of others. I'm not taking credit for this approach, but simply conveying the principle :)
Make sure to check out my post on Commands as well for a nice supplement to this post.

What are domainevents?

A domainevent should be a reusable piece of code that be triggered from anywhere within your application, providing an isolated unit of work. The point of the code I'm about to show you is that you get a readable codebase where you or your fellow teammates can easily understand the flow of the application. Let's get right to it!

Top down

When coding stuff like this, I like to picture what I want to be able to do, and then try and implement the core based on this. I'm going to implement it in a console app, but as you'll see you will be able to use this in any sort of project.

So in essence, what I'd like to do is:

  
 DomainEvents.Raise(new SomeDomainEvent()
                       {
                           Text = "Hello world"
                       });

Or even something like this (inspired by NServiceBus IBus.Publish):

  
 DomainEvents.Raise<SomeDomainEvent>(ev =>
                        {
                            ev.Text = "Hello world";
                        });

This implies that I have a property called DomainEvents, that should be some kind of interface.

  
    private static IDomainEvents DomainEvents;

    static void Main(string[] args)
    {
        DomainEvents.Raise<SomeDomainEvent>(ev =>
                {
                    ev.Text = "Hello world";
                });
    }

I'm going to create a new ClassLibrary that can run alongside my app, that will contain the core logic for my DomainEvents. I'll implement the interface to start with. I also want to restrict the actual event with an interface. Let's just call it IDomainEvent

  
    public interface IDomainEvents
    {
        void Raise<T>(T domainEvent) where T : IDomainEvent;
        void Raise<T>(Action<T> messageConstructor) where T : IDomainEvent, new();
    }

I'm moving abit ahead of myself here, but I'll explain the constraints when I write the implementation of this interface

The IDomainEvent will just be an empty interface

  
    public interface IDomainEvent
    {

    }

So now we've got our interfaces mapped out, and our code compiles. So that means I'm doing something right.

Recap

So just to recap, I've created a IDomainEvent interface and a IDomainEvents interface. The latter defines how we raise our domainevents, but I've still not covered how these events will be handled.

What I want is a DomainEventHandler, and once again, I'll write that out as an interface again. Deferring the actual implementation until I have a structure that seems to work. Let's call it IDomainEventHandler

  
    public interface IDomainEventHandler<T> where T: IDomainEvent
    {
        void Handle(T domainEvent);
    }

The handler should accept a class T of type IDomainEvent, and it contains a single method called Handle. This is where the code to actually handle the event will go.

Implementation

So, following the initial wishlist-code, the SomeDomainEvent should be handled by a class that looks something like this:

  
    public class SomeDomainEventHandler: IDomainEventHandler<SomeDomainEvent>
    {
        public void Handle(SomeDomainEvent domainEvent)
        {
            // Handling the event right here
        }
    }

Looking at this, I can now see that the responsibility of the IDomainEvents implementation should be to find the appropriate implementations of IDomainEventHandler for the given IDomainEvent, and execute the Handle method on these. I guess it's time for some reflection magic and perhaps some Dependency Injection!

First off, I know my IDomainEventHandler is going to need two methods:

  
    public class DomainEvents : IDomainEvents
    {
        public void Raise<T>(T domainEvent) where T : IDomainEvent
        {
            throw new NotImplementedException();
        }

        public void Raise<T>(Action<T> messageConstructor) where T : IDomainEvent, new()
        {
            throw new NotImplementedException();
        }
    }

I'm picturing the void Raise<T>(Action<T> messageConstructor) method can simply call the void Raise<T>(T domainEvent), so we'll implement the lookup code in the latter.

The code needs to be able to do two things:
1. Find all the handlers that implements IDomainEventHandler<T>
2. Execute the handle method for those implementations.

I'm going to start with a private helpermethod to find the implementations of the handlers.

  
    private IEnumerable<dynamic> GetHandlersFor<T>() where T : IDomainEvent
    {
        var handlerType = typeof(IDomainEventHandler<>);
        var genericHandlerType = handlerType.MakeGenericType(typeof(T));

        throw new NotImplementedException();
    }

So far this is pretty basic reflection stuff, as I'm just making a Type object based on my interfaces and the type of T that is passed in. Now that I have the correct type, I need to be able to resolve the implementation somehow. This is where I'll introduce dependency injection.

Given that I'm going to need some sort of injection here, I'll define another interface that my DomainEvents class can rely on. I'll create an interface that makes it simple to make implementations for different types of IoC frameworks:

  
    public interface IDependencyResolver
    {
        T GetService<T>();
        IEnumerable<T> GetServices<T>();
        object GetService(Type type);
        IEnumerable<object> GetServices(Type type);
    }

This is a pretty standard interface that I've seen in several other project, so if you're familiar with Dependency Injection there should be nothing really new here.

Pulling this into our DomainEvents implementation the code would now look like this

  
    public class DomainEvents : IDomainEvents
    {

        private readonly IDependencyResolver _resolver;

        public DomainEvents(IDependencyResolver resolver)
        {
            _resolver = resolver;
        }

        public void Raise<T>(T domainEvent) where T : IDomainEvent
        {
            throw new NotImplementedException();
        }

        public void Raise<T>(Action<T> messageConstructor) where T : IDomainEvent, new()
        {
            throw new NotImplementedException();
        }

        private IEnumerable<dynamic> GetHandlersFor<T>() where T : IDomainEvent
        {
            var handlerType = typeof(IDomainEventHandler<>);
            var genericHandlerType = handlerType.MakeGenericType(typeof(T));

            return _resolver.GetServices(genericHandlerType);
        }
    }

It's starting to take form now, and the only thing missing now is the actual Raise method implementations. Now that we have our helper-method, that should be pretty straight forward:

  
    public class DomainEvents : IDomainEvents
    {

        private readonly IDependencyResolver _resolver;

        public DomainEvents(IDependencyResolver resolver)
        {
            _resolver = resolver;
        }

        public void Raise<T>(T domainEvent) where T : IDomainEvent
        {
            foreach (var handler in GetHandlersFor<T>())
            {
                handler.Handle(domainEvent);
            }
        }

        public void Raise<T>(Action<T> messageConstructor) where T : IDomainEvent, new()
        {
            var message = new T();
            messageConstructor(message);
            Raise(message);
        }

        private IEnumerable<dynamic> GetHandlersFor<T>() where T : IDomainEvent
        {
            var handlerType = typeof(IDomainEventHandler<>);
            var genericHandlerType = handlerType.MakeGenericType(typeof(T));

            return _resolver.GetServices(genericHandlerType);
        }
    }

As you see, I'm creating a new T() in Raise<T>(Action<T> messageConstructor), hence the need for the new() constraint. Also, in Raise<T>(T domainEvent) all I need to do is enumerate the result from GetHandlers and call Handle. I can do this, since I'm returning a list of dynamic objects, and the binding will occur runtime. But I know of course that result will be of type IDomainEventHandler, so from that I know that it will hvae the method Handle.

That concludes the implementation of our DomainEvent-framework. So how would we use this with a IoC framework? Let's look at the implementation using Ninject

  
    public class NinjectDependencyResolver: IDependencyResolver
    {
        private readonly IKernel _kernel;

        public NinjectDependencyResolver(IKernel kernel)
        {
            _kernel = kernel;
        }

        public T GetService<T>()
        {
            return _kernel.Get<T>();
        }

        public IEnumerable<T> GetServices<T>()
        {
            return _kernel.GetAll<T>();
        }

        public object GetService(Type type)
        {
            return _kernel.Get(type);
        }

        public IEnumerable<object> GetServices(Type type)
        {
            return _kernel.GetAll(type);
        }
    }

If you've worked with Ninject, that should be pretty understandable. So what about registering all our DomainEventHandlers?

For that we want to include an extension for Ninject, called Ninject.Extensions.Convensions, which provides us with alot more flexibility when registering components in the Ninject kernel. With this, we can bind by convension, default interfaces and several goodies (that might be very familiar if you've worked with Castle). So in our program.cs class:

  
    private static IKernel _kernel;
    private static void SetupKernel()
    {
        _kernel = new StandardKernel();
        _kernel.Bind(syntax => syntax
            .FromAssemblyContaining<SomeDomainEventHandler>()
            .SelectAllTypes()
            .InNamespaceOf<SomeDomainEventHandler>()
            .BindAllInterfaces()
            .Configure(binding => binding.InSingletonScope()));

        _kernel.Bind(
            syntax => syntax
                .FromAssemblyContaining<IDomainEvent>()
                .SelectAllClasses()
                .BindDefaultInterface()
                .Configure(binding => binding.InSingletonScope()));
        _kernel.Bind<IDependencyResolver>().To<NinjectDependencyResolver>();
    }

What this does is first to find the namespace containing my eventhandler, and binding all the interfaces to their implementations. No need to do it manually for each handler. Second, it binds up all the interfaces in the class library containing my DomainEvents implementation. Finally it binds the IDependencyResolver to my NinjectDependencyResolver implementation.

Let's look at the complete code in our console application:

  
    class Program
    {
        private static IDomainEvents DomainEvents {
            get { return _kernel.Get<IDomainEvents>(); }
        }

        static void Main(string[] args)
        {
            SetupKernel();
            DomainEvents.Raise<SomeDomainEvent>(ev =>
                                {
                                    ev.Text = "Hello world";
                                });
        }

        private static IKernel _kernel;
        private static void SetupKernel()
        {
            _kernel = new StandardKernel();
            _kernel.Bind(syntax => syntax
                .FromAssemblyContaining<SomeDomainEventHandler>()
                .SelectAllTypes()
                .InNamespaceOf<SomeDomainEventHandler>()
                .BindAllInterfaces()
                .Configure(binding => binding.InSingletonScope()));

            _kernel.Bind(
                syntax => syntax
                    .FromAssemblyContaining<IDomainEvent>()
                    .SelectAllClasses()
                    .BindDefaultInterface()
                    .Configure(binding => binding.InSingletonScope()));
            _kernel.Bind<IDependencyResolver>().To<NinjectDependencyResolver>();
        }
    }

As you see, I now resolve the IDomainEvents implementation in order to get it constructed with the correct IDependencyResolver. Changing from Ninject to Castle or some other framework of your choice should be pretty trivial.

And the SomeEventDomainHandler

  
    public class SomeDomainEventHandler: IDomainEventHandler<SomeDomainEvent>
    {
        public void Handle(SomeDomainEvent domainEvent)
        {
            Console.WriteLine(domainEvent.Text);
        }
    }

Running the application, should now output "Hello world" in the console window. So why is this cool? Well, first off, we can simply create a new domainhandler for the SomeDomainEvent:

  
    public class ThisRocksEventHandler: IDomainEventHandler<SomeDomainEvent>
    {
        public void Handle(SomeDomainEvent domainEvent)
        {
            Console.WriteLine("{0} - ThisRocks! {1}", DateTime.Now, domainEvent.Text);
        }
    }

When we now run the application, we'll get both "Hello world", and something like "12.08.2012 - ThisRocks! Hello World" written to the console.

Since we're using the IDependencyResolver interface to get the correct handlers, that means we can even do constructor injection in our handlers:

  
    public class ThisRocksEventHandler: IDomainEventHandler<SomeDomainEvent>
    {
        private readonly ITextProcessor _textProcessor;

        public ThisRocksEventHandler(ITextProcessor textProcessor)
        {
            _textProcessor = textProcessor;
        }

        public void Handle(SomeDomainEvent domainEvent)
        {
            Console.WriteLine("{0} - ThisRocks! {1}", DateTime.Now, _textProcessor.ProcessText(domainEvent.Text));
        }
    }

Pretty sweet, eh?

Wrapping up

In this post I've showed how you can implement a reusable domainevent handling framework that utilizes the IoC framework of your choice. I'm pretty sure it can be expanded, improved or whatnot. If you have any ideas, feel free to fork the repo at Github (update: The URL was dead - updated now. The project on GitHub also contains code for the Commands-blogpost)