Nservicebus вопрос о сериализации производных типов - PullRequest
3 голосов
/ 12 мая 2010

для настройки контекста, я обмениваюсь сообщениями между моим клиентом nServiceBus и сервером nSerivceBus.это пространство имен xyz.Messages и и класс, Message: IMessage

У меня есть больше сообщений, которые находятся в других библиотеках, таких как 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, он успешно отправляет сообщение и на сервер, я получаю правильный тип.

например,

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 ]

3 голосов
/ 17 июня 2010

Вот ответ Уди

Прежде всего, очень необычно, чтобы клиентские очереди появлялись в конфигурации сервера. Я бы порекомендовал удалить это.

Во-вторых, я предполагаю, что вы не используете общий хост, поскольку вы вручную инициализируете шину - это нормально, просто хотел проверить. Кроме того, вы используете один и тот же код для инициализации как на стороне клиента, так и на стороне сервера? Это не особенно рекомендуется. По крайней мере, сторона сервера должна быть транзакционной (если вы не идете по некоторому идемпотентному маршруту обмена сообщениями).

В-третьих, то, что вы пытаетесь сделать, должно работать нормально, если вы используете бинарный сериализатор. Причиной является предположение о более тесной связи и меньшая потребность в явных контрактах на сообщения. Сериализатор XML, с другой стороны, создан для обеспечения более явной схемы сообщений - поэтому он не поддерживает такие типы производных типов.

Сценарии, в которых вы можете захотеть использовать производные типы в своих сообщениях (запросы, прямое манипулирование данными и т. Д.), Обычно являются областями, в которых вам не следует использовать обмен сообщениями с самого начала.

Надеюсь, это чем-то поможет.

- Уди Дахан

3 голосов
/ 20 мая 2010

NServiceBus XmlSerializer не поддерживает это - см. Ветку http://tech.groups.yahoo.com/group/nservicebus/message/6549

BinarySerializer будет работать, или вы можете реализовать пользовательский сериализатор сообщений. По моему мнению, DataContractSerializer должен быть доступен из коробки для сценариев сериализации, которые не обрабатываются XmlSerializer.

Обратите внимание, что, выполнив это, вы, вероятно, потеряете поддержку версий сообщений NSB - если это важно для вас, я бы предложил переосмыслить дизайн вашего сообщения.

...