NServiceBus: specifying message order

I use NServiceBus in my own process (therefore not using Generic Host), and I would like to have several message handlers for messages in a specific order. For Generic Host, you would do ISpecifyMessageHandlerOrdering , but I don’t know how to do this when hosting my own NServiceBus process, since this interface is defined in NServiceBus.Host.exe , and I could not find another way to do this.

The purpose of this is to authenticate the user: before calling the actual message handler, I would first want to authenticate the sender of the message, which will happen in another, more general, message handler. The message will be of a type that contains the encrypted username and password and / or session identifier. This type will be used for almost all commands sent to the server (everything except the login, I think). Is this a way to authenticate users using NServiceBus?

He currently takes the second handler, but not in the correct order.

Update

As David suggested, I tried to create an IMessageModule and read the headers from CurrentMessageContext to authenticate the user.

Here I ran into some problems:

  • The first time a message is sent, bus.CurrentMessageContext is null . Each time after that, it fills correctly, and I can read the headers.
  • Calling bus.DoNotContinueDispatchingCurrentMessageToHandlers when the user is not authenticated does not stop calling message handlers. Also, bus.Return(errorCode) does not exist. Are there any other ways I can do this?
+4
source share
3 answers

As described in the NServiceBus FAQ on the documentation page:

http://docs.particular.net/nservicebus/handlers/handler-ordering

How to specify the order in which handlers are used?

If you are writing your own host:

 NServiceBus.Configure.With() ... .UnicastBus() .LoadMessageHandlers(First<H1>.Then<H2>().AndThen<H3>().AndThen<H4>() //etc) ... 

If you are using a shared host

 public class EndpointConfig : IConfigureThisEndpoint, ISpecifyMessageHandlerOrdering { public void SpecifyOrder(Order order) { order.Specify(First<H1>.Then<H2>().AndThen<H3>().AndThen<H4>() //etc); } } 

If you want to specify only one handler (with your host)

 NServiceBus.Configure.With() ... .UnicastBus() .LoadMessageHandlers<FIRST<YourHandler>>() ... 

If you want to specify only one handler (with a shared host)

 public class EndpointConfig : IConfigureThisEndpoint, ISpecifyMessageHandlerOrdering { public void SpecifyOrder(Order order) { order.Specify<FIRST<YourHandler>>(); } } 
+7
source

Another possibility is to implement the base message handler class, which conditionally skips authentication-based processing.

 public abstract class MessageHandlerBase<T> : IMessageHandler<T> where T : IMessage { public abstract void HandleMessage(T message); public void Handle(T message) { if (CredentialsValid(message)) this.HandleMessage(message); } } 
+4
source

Have you considered a message module for this purpose?

 public interface IMessageModule { // Methods void HandleBeginMessage(); void HandleEndMessage(); void HandleError(); } 

Implementing this interface gives you the ability to call code before and after each message. If you enter IBus, you can access the current context of the message and from there check the headers and use them to authenticate your messages.

+3
source

All Articles