我在自己的进程中使用NServiceBus(所以不使用通用主机),我想为特定顺序的消息提供多个消息处理程序。对于通用主机,您将实现ISpecifyMessageHandlerOrdering
,但在托管您自己的NServiceBus进程时我不知道如何执行此操作,因为该接口在NServiceBus.Host.exe
中定义,但我无法找到另一种方法。
这样做的目的是用户身份验证:在调用实际的消息处理程序之前,我首先要对消息的发送者进行身份验证,这将发生在另一个更通用的消息处理程序中。该消息的类型包含加密的用户名和密码和/或会话ID。此类型将用于发送到服务器的几乎所有命令(我认为除登录之外的所有命令)。这是使用NServiceBus进行用户身份验证的好方法吗?
目前,它会选择第二个处理程序但不是正确的顺序。
更新
根据David的建议,我尝试创建IMessageModule
并从CurrentMessageContext
读取标头以验证用户身份。
我在这里遇到了一些问题:
bus.CurrentMessageContext
为null
。每次之后,它都被正确填写,我可以阅读标题。bus.DoNotContinueDispatchingCurrentMessageToHandlers
不会阻止调用消息处理程序。 bus.Return(errorCode)
也没有。还有其他方法吗? 答案 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,您可以访问当前的消息上下文,并从那里检查标题并使用它来验证您的消息。