NServiceBus:指定消息顺序

时间:2010-11-04 12:54:21

标签: c# authentication messaging nservicebus

我在自己的进程中使用NServiceBus(所以使用通用主机),我想为特定顺序的消息提供多个消息处理程序。对于通用主机,您将实现ISpecifyMessageHandlerOrdering,但在托管您自己的NServiceBus进程时我不知道如何执行此操作,因为该接口在NServiceBus.Host.exe中定义,但我无法找到另一种方法。

这样做的目的是用户身份验证:在调用实际的消息处理程序之前,我首先要对消息的发送者进行身份验证,这将发生在另一个更通用的消息处理程序中。该消息的类型包含加密的用户名和密码和/或会话ID。此类型将用于发送到服务器的几乎所有命令(我认为除登录之外的所有命令)。这是使用NServiceBus进行用户身份验证的好方法吗?

目前,它会选择第二个处理程序但不是正确的顺序。

更新

根据David的建议,我尝试创建IMessageModule并从CurrentMessageContext读取标头以验证用户身份。

我在这里遇到了一些问题:

  • 我第一次发送消息时,bus.CurrentMessageContextnull。每次之后,它都被正确填写,我可以阅读标题。
  • 当用户未经过身份验证时调用bus.DoNotContinueDispatchingCurrentMessageToHandlers不会阻止调用消息处理程序。 bus.Return(errorCode)也没有。还有其他方法吗?

3 个答案:

答案 0 :(得分:7)

如文档页面上的NServiceBus FAQ所述:

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

如何指定调用处理程序的顺序?

如果您正在编写自己的主持人:

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

如果您使用的是通用主机

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

如果您只想指定一个处理程序(使用您自己的主机)

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

如果您只想指定一个处理程序(使用通用主机)

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

答案 1 :(得分:4)

另一种可能性是实现一个基本消息处理程序类,它将根据您的身份验证检查有条件地跳过处理。

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

    }
}

答案 2 :(得分:3)

您是否考虑过此消息模块?

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

实现此接口可以让您在每条消息之前和之后调用代码。如果您注入IBus,您可以访问当前的消息上下文,并从那里检查标题并使用它来验证您的消息。