对于上下文设置,我在nServiceBus客户端和nSerivceBus服务器之间交换消息。它是名称空间xyz.Messages和一个类,Message:IMessage
我有更多其他dll中的消息,例如xyz.Messages.Domain1,xyz.Messages.Domain2,xyz.Messages.Domain3。 以及从基本消息派生的消息,消息。
我将端点定义为:
at client
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="xyz.Messages" Endpoint="xyzServerQueue" />
<add Messages="xyz.Messages.Domain1" Endpoint="xyzServerQueue" />
<add Messages="xyz.Messages.Domain2" Endpoint="xyzServerQueue" />
</MessageEndpointMappings>
</UnicastBusConfig>
在服务器
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="xyz.Messages" Endpoint="xyzClientQueue" />
<add Messages="xyz.Messages.Domain1" Endpoint="xyzClientQueue" />
<add Messages="xyz.Messages.Domain2" Endpoint="xyzClientQueue" />
</MessageEndpointMappings>
</UnicastBusConfig>
并将总线初始化为
IBus serviceBus = Configure.With()
.SpringBuilder()
.XmlSerializer()
.MsmqTransport()
.UnicastBus()
.LoadMessageHandlers()
.CreateBus()
.Start();
现在当我尝试发送Message类型的实例或任何类型的派生类型的Message时,它成功地在服务器上发送消息,我得到了正确的类型。
例如。
Message message= new Message();
Bus.Send(message); // works fine, transfers Message type
message = new MessageDerived1();
Bus.Send(message); // works fine, transfers MessageDerived1 type
message = new MessageDerived2();
Bus.Send(message); // works fine, transfers MessageDerived2 type
我的问题出现在任何类型,比如MessageDerived1,包含Message类型的成员变量,当我将它分配给派生类型时,类型没有通过网络正确传输。它仅作为消息类型传输,而不是派生类型。
public class MessageDerived2 : Message
{
public Message message;
}
MessageDerived2 messageDerived2= new MessageDerived2();
messageDerived2.message = new MessageDerived1();
message = messageDerived2;
Bus.Send(message); // incorrect behaviour, transfers MessageDerived2 correctly, but looses type of MessageDerived2.Message (it deserializes as Message type, instead of MessageDerived1)
非常感谢任何帮助。
由于 TJ
答案 0 :(得分:3)
NServiceBus XmlSerializer不支持此功能 - 请参阅http://tech.groups.yahoo.com/group/nservicebus/message/6549
中的主题BinarySerializer可以使用,或者您可以实现自定义消息序列化程序。在我看来,对于XmlSerializer无法处理的序列化方案,DataContractSerializer应该是开箱即用的。
请注意,通过执行此操作,您可能会失去NSB消息版本控制支持 - 如果这对您很重要,我建议您重新考虑您的消息设计。
答案 1 :(得分:3)
这是Udi的回复
首先,让客户端队列出现在服务器的配置中是非常罕见的。我建议删除它。
其次,我假设您没有使用通用主机,因为您手动初始化总线 - 这很好,只是想检查。 另外,您是否在客户端和服务器端初始化时使用相同的代码?不特别推荐。 至少,服务器端应该是事务性的(除非你要使用一些幂等的消息传递路由)。
第三,如果您使用二进制序列化器,那么您尝试做的事情应该可以正常工作。原因是假设耦合更紧密,对显式消息合同的需求更少。另一方面,XML Serializer构建为强制更明确的消息模式 - 因此不支持这些类型的派生类型。
您可能希望在消息中使用派生类型(查询,直接数据操作等)的场景通常是您不应该首先使用消息传递的区域。
希望在某种程度上有所帮助。
- Udi Dahan