使用NServiceBus,您可以通过界面订阅,例如:
public class MyEvent: ISomeInterface {}
public class Handler: IHandleMessages<ISomeInterface>{...}
这一切似乎都很愉快,但是当你有多个接口时,例如:
public class MyEvent: ISomeInterface, ISomeOtherInterface {}
public class Handler: IHandleMessages<ISomeInterface>{/*Works fine*/}
public class Handler: IHandleMessages<ISomeOtherInterface>{/*Doesnt work*/}
在使用pub / sub时,无论是哪种情况都正确订阅了消息,但是当消息实际发布时,接收服务错误包括:
无法找到消息类型的处理程序:ISomeInterface
似乎只有在您处理的接口是发送的消息类的第一个接口时才会起作用。如果我在第二个处理程序周围的实际事件实现上交换接口的顺序工作正常,但第一个错误与类似的消息(即接口的顺序是什么导致问题)
有没有办法按接口处理消息,无论接口在构造消息时的顺序是什么?
我尝试使用NSB 3和NSB 4的处理程序都产生相同的结果。
修改
根据要求,我正在使用的订阅者配置的更详细的片段。我还整理了一个最小的repro pub / sub应用程序来演示我遇到的问题(on github here)。
Configure.Features.Disable<NServiceBus.Features.TimeoutManager>().Disable<NServiceBus.Features.SecondLevelRetries>();
Configure.With()
.DefineEndpointName("nsbinterfaces.subscriber")
.DefiningEventsAs(t => t.Namespace != null && t.Namespace.Contains(".Events"))
//.NinjectBuilder(kernel)
.DefaultBuilder()
.UseTransport<Msmq>()
.PurgeOnStartup(false)
.MsmqSubscriptionStorage("nsbinterfaces.subscriber")
.UnicastBus()
.LoadMessageHandlers()
.ImpersonateSender(false)
.CreateBus()
.Start(
() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
答案 0 :(得分:2)
在看了一眼后,我想我知道发生了什么。
您的发布者了解它自己的事件(MyEvent)以及它实现的两个接口。这两个接口位于共享的程序集中。
您的订阅者对MyEvent一无所知,因此它不知道它实现了两个接口。它既可以是ISomeInterface,也可以是ISomeOtherInterface,因此它将其反序列化为这些类型中的一个。
由于接口的顺序似乎决定了它接收的消息类型,我猜想NSB会将消息反序列化为它所知道的第一种类型(每个进程)。
<?xml version="1.0"?>
<Messages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://tempuri.net/NsbInterfaces.Publisher.Events"
xmlns:baseType="NsbInterfaces.Events.ISomeInterface"
xmlns:baseType1="NsbInterfaces.Events.ISomeOtherInterface">
<MyEvent></MyEvent>
</Messages>
答案 1 :(得分:1)
答案 2 :(得分:0)
我在NSB论坛上问了这个问题并将其转换为一个问题,看起来应该在软件的v5中解决。 (https://github.com/Particular/NServiceBus/issues/2301)
在修复之前我认为有2个选项: