3

对于上下文设置,我在我的 nServiceBus 客户端和 nSerivceBus 服务器之间交换消息。它是命名空间 xyz.Messages 和一个类 Message : IMessage

我在其他 dll 中有更多消息,例如 xyz.Messages.Domain1、xyz.Messages.Domain2、xyz.Messages.Domain3。以及从基本消息 Message 派生的消息。

我将端点定义为:

 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= 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

4

2 回答 2

3

Here is Udi's reply

First of all, it is highly unusual to have the client queues appear in the server's config. I'd recommend removing that.

Second, I assume that you're not using the generic host as you're manually initializing the bus - that's fine, just wanted to check. Also, are you using the same code for both client and server side initialization? That isn't particularly recommended. At the very least, the server side should be transactional (unless you're going down some idempotent messaging route).

Third, what you're trying to do should work just fine if you use the Binary Serializer. The reason is the assumption of tighter coupling and less of a need for explicit message contracts. The XML Serializer, on the other hand, is built to enforce more explicit message schema - therefore not supporting those kinds of derived types.

The scenarios where you might want to use derived types in your messages (queries, straight data manipulation, etc) are usually the areas where you shouldn't be using messaging to begin with.

Hope that helps in some way.

-- Udi Dahan

于 2010-06-17T13:19:53.150 回答
3

NServiceBus XmlSerializer 不支持这一点 - 请参阅http://tech.groups.yahoo.com/group/nservicebus/message/6549上的线程

BinarySerializer 将起作用,或者您可以实现自定义消息序列化器。在我看来,对于 XmlSerializer 无法处理的序列化场景,DataContractSerializer 应该是开箱即用的。

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

于 2010-05-20T00:45:47.877 回答