NServiceBus自定义消息处理程序类型

时间:2012-01-27 00:51:36

标签: c# nservicebus

NServiceBus中是否有办法替换IHandleMessages<>我自己的这个接口版本的处理程序与NServiceBus没有很强的联系?

我找到了替换事件/命令标记接口的方法(通过NServiceBus 3 Unobtrusive语法),但没有办法对实际的处理程序做同样的事情。我试图这样做,以消除我的处理程序和NServiceBus之间的耦合。

3 个答案:

答案 0 :(得分:1)

NServiceBus 3.0 Unobtrusive Mode(参见Andreas Ohlund's article on this)的原因是,如果不同的端点运行不同版本的NServiceBus,多个服务之间共享的事件定义可能会遇到麻烦,因为NServiceBus.dll上的版本是你的依赖于不相称。

这个论点并不包含消息处理程序(实现IHandleMessages的类)本身。没有共享处理程序。根据定义,消息处理程序与NServiceBus耦合。

答案 1 :(得分:1)

NServiceBus似乎无法做到这一点。

我尽可能不引人注目的方式是创建一个NServiceBus代理来将消息转发到我自己的总线,这使得NServiceBus引用远离我的大多数项目。

答案 2 :(得分:1)

我发现只需要很少的代码就可以了:

1)创建一个实现IHandleMessages<TMessage>的泛型类,并实现Handle方法,使其找到或创建自定义处理程序的正确实例(来自DI容器,静态注册表等)。在此示例中,假设您已MyCustomHandler类使用void HandleMessageMyWay(object message)方法接受任何消息类型:

public class MessageHandlerAdapter<TMessage>
   : IHandleMessages<TMessage>
{
    public void Handle(TMessage message)
    {
        new MyCustomHandler().HandleMessageMyWay(message);
    }
}

它是一个开放的泛型,因此NServiceBus不会发现它是一个有效的处理程序,因为你需要一个封闭的泛型(TMessage是一个具体的类型,如MyMessage1),被NServiceBus看作是一个处理程序对于具体类型。

2)实施ISpecifyMessageHandlerOrdering。在它的SpecifyOrder方法中,(在运行时)为您要支持的每种消息类型设置一个封闭的通用适配器类型:

public class MessageHandlerAdapterLister : ISpecifyMessageHandlerOrdering
{
    public void SpecifyOrder(Order order)
    {
        //You would normally iterate through your message types (over DI registry or some other registry of messages):
        var adapterType1 = typeof(MessageHandlerAdapter<>).MakeGenericType(typeof(MyMessage1));
        var adapterType2 = typeof(MessageHandlerAdapter<>).MakeGenericType(typeof(MyMessage2));

        order.Specify(new[] { adapterType1, adapterType2 });
    }
}
NServiceBus会自动发现

ISpecifyMessageHandlerOrdering个实例。这些通常用于指定NServiceBus发现的处理程序类型的顺序。显然,当您指定尚未发现的类型时(例如我们在运行时创建的封闭通用适配器类型),它只会将它们添加到注册表中。

这就是你所需要的一切。 NServiceBus将通过开放的通用MyMessage1路由MyMessage2IHandleMessages<TMessage>,然后将处理委派给您的自定义类。