Handler Ordering

Component: NServiceBus
NuGet Package NServiceBus (3.x)
Standard support for version 3.x of NServiceBus has expired. For more information see our Support Policy.

In the past, message handlers used to be the only way to implement cross-cutting concerns like authentication, authorization, and certain kinds of validation. As those concerns needed to be applied before any other logic, it was necessary to run those handlers before all other message handlers. These message handler classes implemented IHandleMessage<IMessage> or IHandleMessage<Object> so that they would handle all incoming messages.

It is now recommended to plug into the message handling pipeline to implement these cross-cutting concerns.

If it is not possible to migrate this kind of functionality out of message handlers, there are a number of ways to specify the order in which they will be executed.

All message handlers in the endpoint will execute in the same transaction scope.

Overview of the implementation

  1. Find the list of possible handlers for a message.
  2. If an order has been specified for any of those handlers, move them to the start of the list.
  3. Execute the handlers.

The remaining handlers (i.e. ones not specified in the ordering) are executed in a non-deterministic order.

With the configuration API

var configUnicastBus = configure.UnicastBus();
configUnicastBus.LoadMessageHandlers(First<HandlerB>.Then<HandlerA>().AndThen<HandlerC>());

Specifying one handler to run first

public class MySpecifyingFirst :
    ISpecifyMessageHandlerOrdering
{
    public void SpecifyOrder(Order order)
    {
        order.SpecifyFirst<HandlerB>();
    }
}

Specifying multiple handlers to run in order

public class MySpecifyingOrder :
    ISpecifyMessageHandlerOrdering
{
    public void SpecifyOrder(Order order)
    {
        order.Specify(First<HandlerB>.Then<HandlerA>().AndThen<HandlerC>());
    }
}

Last modified