NServiceBus: specifying message order

↘锁芯ラ 提交于 2019-12-19 08:39:45

问题


I'm using NServiceBus in it's own process (so not using the Generic Host) and I would like to have multiple message handlers for a message in a specific order. For the Generic Host, you would implement ISpecifyMessageHandlerOrdering, but I don't know how to do this when hosting your own NServiceBus process since that interface is defined in NServiceBus.Host.exe and I haven't been able to find another way to do this.

The purpose of this is user authentication: before the actual message handler is invoked, I would first like to authenticate the sender of the message, which would happen in a different, more generic, message handler. The message will be of a type that contains the encrypted user name and password and/or a session ID. This type will be used for almost all commands sent to the server (everything but login I think). Is this an OK way to do user authentication using NServiceBus?

Currently, it picks up the second handler but not in the right order.

Update

As suggested by David I tried creating a IMessageModule and reading the headers from the CurrentMessageContext to authenticate the user.

I ran into some problems here:

  • The first time I send a message, the bus.CurrentMessageContext is null. Every time after that, it's filled in correctly and I can read the headers.
  • Calling bus.DoNotContinueDispatchingCurrentMessageToHandlers when the user is not authenticated does not stop the message handlers from being invoked. Neither does bus.Return(errorCode). Are there other ways I can do that?

回答1:


As described in the NServiceBus FAQ on the documentation page:

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

How do I specify the order in which handlers are invoked?

If you're writing your own host:

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

If you're using the generic host

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

If you only want to specify a single handler (with your own host)

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

If you only want to specify a single handler (with the generic host)

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



回答2:


Another possibility would be to implement a base message handler class that would conditionally skip the handling based on your authentication check.

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);

    }
}



回答3:


Have you considered a message module for this purpose?

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

Implementing this interface gives you a point to have code called before and after every message. If you inject an IBus, you can access the current message context, and from there inspect headers and use that to authenticate your messages.



来源:https://stackoverflow.com/questions/4096841/nservicebus-specifying-message-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!