Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping NServiceBus.IHandleMessages

Tags:

nservicebus3

I am being asked to develop a layer that will act as a generic bus without any direct references to NServiceBus. Which so far thanks to support for unobtrusive messages isn't too hard. Except now I've been asked to provide our own definition for IHandleMessages and find a way to map it during wireup. So I'm thinking something like this:

    public class MessageHandlerAdapter<T> : IHandleMessages<T>
{
    IUnityContainer container;

    public MessageHandlerAdapter(IUnityContainer container)
    {
        this.container = container;
    }

    #region IMessageHandler<T> Members

    public void Handle(T message)
    {
        var handler = container.Resolve<IHandle<T>>();
        handler.Handle(message);
    }

    #endregion
}

Where IHandle would be our own definition (which by the way is exactly the same as IHandleMessages). I would expect to reflect over the AppDomain and find all classes that implemented IHandle and Register them with the container, then register a MessageHandlerAdapter with the same type T.

My problem is I haven't used NServiceBus for almost 2 years and I don't remember where to hook into this kind of functionality in the NSB pipeline.

like image 637
Mark J Miller Avatar asked Jan 17 '13 21:01

Mark J Miller


1 Answers

You probably wont like this answer but... Don't write abstraction layers for tools you use.

I have seen many instances where people attempt to write an abstraction layer around certain tools. Mostly the cases are logging and ORM frameworks. Now people have good intentions when they do this. They want to "be able to switch library X easily". Unfortunately this is a bad idea for several reasons

  • Incompatible concepts. In your example you might extract out the concept of a NSB Saga timeout. However there is no guarantee that this concept will be behave the same way in the theoretical "library to switch to in the future", or that the concept will exist at all. Usually these "abstraction layers" end up being a direct map of single library and are not portable at all.
  • Added complexity. You will add a large amount of complexity to your solution.
  • Samples wont work. when you look at samples of the library you will need to "map in your " over to your abstraction layer
  • Barrier to entry. While new developers joining your team may have used the library in question they will have no understanding of your wrapper
  • Fighting against the API. No library is ever designed with the feature "be able to extract a common implementation" in mind. Because of this the API will actively fight you performing this activity.
  • Debugging. An extra layer will make it harder to debug your solution
  • Performance. In general more code is slower code. Also often these abstraction layers need to use reflection...
  • Support. You will make it harder to get support from the people who own the library because it will be difficult to document how you interact with the library.
  • On-going changes. Every time the library in question adds or changes to API you will have to add mapping code before you can leverage that functionality in you solution.
  • Documentation. Often huge amounts of person hours has gone into creating documentation for the libraries. It will be a significant effort, on your part, getting the documentation for your abstraction up to that level.

It all comes down to time. You are attempting to spend time now abstracting the tool. With the hope of saving a larger amount of time in the future. The problem is you will spend much more time creating and maintaining this abstraction than you will ever save IF you decide to switch. This should be your response to your coworkers.

Here is an interesting post from Ayende talking about the evils of abstraction. Much of it is applicable to this scenario http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer To quote

...try to avoid needless complexity... Adding additional layers of abstractions usually only make it hard.

like image 133
Simon Avatar answered Oct 03 '22 18:10

Simon