I’ve been trying for a while now to figure out how to do edge components in NServiceBus, which is a pattern that is mentioned in the excellent SOA Patterns book which I recently finished. They are similar to action filter attributes in ASP.Net MVC - allowing you to implement cross-cutting concerns by running some code before and after actions.

In my case, the main thing I want to do is write a log entry for every message that comes in and is processed showing how long it took to execute. I tried a number of things:

  • PostSharp - very cool, but I think a bit annoying because every developer on the team would have to register a copy and we rotate people in and out of my team. I’ll probably look into this in the future because it seems like a really useful piece of technology.
  • Windsor Interceptors - also pretty cool, but unfortunately if you attach an interceptor to a handler class, it changes the type and NSB no longer recognises it as a handler, so ruled that out pretty quickly.

After these two problems I finally stumbled onto the IManageUnitsOfWork interface that comes with NServiceBus and allows you to run an action before and after every handler invocation. To set it up, first implement it:

public class LoggingUnitOfWork : IManageUnitsOfWork
{
    public IBus Bus { get; set; }
    public void Begin()
    {
        Console.WriteLine("Before invocation");
    }
    public void End(Exception ex = null)
    {
        Console.WriteLine("After invocation");
        // use Bus.CurrentMessageContext to get information about the current message being handled
    }
}

Then, register it in your container. I use Windsor:

public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    public void Init()
    {
        var container = new Castle.Windsor.WindsorContainer();
        container.Register(
            Component.For<IManageUnitsOfWork>()
                .ImplementedBy<LoggingUnitOfWork>()
                .LifeStyle.Transient.Named("LoggingUnitOfWork")
        );
        Configure.With()
            .CastleWindsorBuilder(container);
    }
}

And that’s it. You can use the injected IBus instance to do just about anything. From what I can tell you can register as many implementations of IManageUnitOfWork as you want, and all of them will be executed, so for example if you’re using the built-in NHibernate plugins this won’t stomp all over its unit of work management system.