Nservicebus派生类型的serization问题

时间:2010-05-12 07:55:29

标签: wcf xml-serialization nservicebus

对于上下文设置,我在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

2 个答案:

答案 0 :(得分:3)

NServiceBus XmlSerializer不支持此功能 - 请参阅http://tech.groups.yahoo.com/group/nservicebus/message/6549

中的主题

BinarySerializer可以使用,或者您可以实现自定义消息序列化程序。在我看来,对于XmlSerializer无法处理的序列化方案,DataContractSerializer应该是开箱即用的。

请注意,通过执行此操作,您可能会失去NSB消息版本控制支持 - 如果这对您很重要,我建议您重新考虑您的消息设计。

答案 1 :(得分:3)

这是Udi的回复

首先,让客户端队列出现在服务器的配置中是非常罕见的。我建议删除它。

其次,我假设您没有使用通用主机,因为您手动初始化总线 - 这很好,只是想检查。 另外,您是否在客户端和服务器端初始化时使用相同的代码?不特别推荐。 至少,服务器端应该是事务性的(除非你要使用一些幂等的消息传递路由)。

第三,如果您使用二进制序列化器,那么您尝试做的事情应该可以正常工作。原因是假设耦合更紧密,对显式消息合同的需求更少。另一方面,XML Serializer构建为强制更明确的消息模式 - 因此不支持这些类型的派生类型。

您可能希望在消息中使用派生类型(查询,直接数据操作等)的场景通常是您不应该首先使用消息传递的区域。

希望在某种程度上有所帮助。

- Udi Dahan