NServiceBus中是否有办法替换IHandleMessages<>我自己的这个接口版本的处理程序与NServiceBus没有很强的联系?
我找到了替换事件/命令标记接口的方法(通过NServiceBus 3 Unobtrusive语法),但没有办法对实际的处理程序做同样的事情。我试图这样做,以消除我的处理程序和NServiceBus之间的耦合。
答案 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
路由MyMessage2
和IHandleMessages<TMessage>
,然后将处理委派给您的自定义类。