Сложные сообщения и десериализация Masstransit

Я публикую сообщение в MT, которое имеет несколько свойств типа Object, так как я не знаю тип во время компиляции. Когда я получаю сообщение в потребителе, я вижу, что свойства типа Object заполнены экземплярами Newtonsoft JObject. Класс JObject находится в сборке ILMerged Newtonsoft.Json в Masstransit.dll. JObject-Class в этой сборке помечен как внутренний. Всякий раз, когда я пытаюсь передать значение свойства JObject, предоставленному Nuget-Assembly Newtonsoft.Json, это не удается.

Итак, мои вопросы:

  • Как правильно передать значение свойства JObject?
  • Почему актерский состав проваливается? То есть, какие здесь сложности у clr?
  • Могу ли я получить необработанное, несериализованное тело сообщения в моем потребителе?

Спасибо.


person Joachim Rosskopf    schedule 06.02.2012    source источник


Ответы (3)


Вы не можете использовать сериализацию JSON, если вы выполняете ввод во время выполнения для любых контрактов сообщений. Если вы хотите сделать это, вам потребуется использовать двоичный сериализатор.

Вы не можете получить доступ к необработанному, несериализованному телу сообщения; если сообщение не может быть десериализовано, код пользователя не вызывается.

Наличие каких-либо типов, помеченных как внутренние, не позволит нам десериализовать сообщение. Конструктор не может быть вызван, поэтому объект не создается. Я не уверен, что бинарный сериализатор позволит вам обойти это ограничение, не то, что я тестировал.

Если у вас есть другие вопросы, вы также можете присоединиться к списку рассылки, https://groups.google.com/forum/#!forum/masstransit-discuss.

person Travis    schedule 06.02.2012
comment
Спасибо за ваше предложение. Но, к сожалению, даже типы сообщений, включенные в последний пакет Masstransit-NuGet (пульс, подписка и т. д.), похоже, не работают с BinarySerializer. Они не украшены атрибутом Serializable. - person Joachim Rosskopf; 07.02.2012
comment
Пожалуйста, отправьте запрос (или, что еще лучше, запрос на вытягивание), чтобы они были оформлены должным образом, чтобы работала двоичная сериализация. - person Chris Patterson; 07.02.2012
comment
Разработка была бы хорошим началом. Сегодня Крис объединял кучу вещей, так что, скорее всего, скоро выйдет новый релиз. Если вы выберете не ту ветку, мы всегда сможем ее подобрать, так что это не проблема. - person Travis; 08.02.2012

Как один из создателей MassTransit, если вы включаете

public object MyMessageProperty { get; set; }

В вашем контракте сообщений вы делаете это неправильно. Используйте строго типизированные функции публикации платформы вместо того, чтобы выполнять собственную динамическую отправку поверх отправки, уже выполняемой системой публикации/подписки внутри MT.

person Chris Patterson    schedule 07.02.2012
comment
Как видите, я упомянул в своем решении, что знаю, что вы не планировали использовать полиморфную отправку. Тем не менее, у меня есть сообщения с комбинациями типов. Было бы довольно много сообщений, чтобы представить все комбинации в типизированном виде. - person Joachim Rosskopf; 07.02.2012
comment
Да, сообщений довольно много, но поддерживаются наследование и интерфейсы, так что вы действительно можете делать больше интересных вещей, используя типы. Вы можете начать наблюдать за событиями, просматривать части сообщения без необходимости (x is Y) везде. Это действительно лучший способ сделать это, быть явным и преднамеренным против хаоса. Это очень важно, когда код покидает ваш разум и начинает использоваться другими. - person Chris Patterson; 07.02.2012

Моя вышеописанная проблема, вероятно, возникла просто из-за неправильного представления о моей системе обмена сообщениями. Но я нашел неприятный обходной путь для преобразования вложенных объектов JObject в правильные объекты домена:

protected bool TryConvertJObjectToDtoOfType<T>(Object jObjectInDisguise, out T dto)
     where T: BpnDto
{
    try
    {
         if (jObjectInDisguise.GetType().Name != typeof(JObject).Name)
             throw new ArgumentException("Object isn't a JObject", "jObjectInDisguise");

        var json = jObjectInDisguise.ToString();
        var settings = new JsonSerializerSettings()
        {
            MissingMemberHandling = MissingMemberHandling.Error
        };

        dto = JsonConvert.DeserializeObject<T>(json, settings);
        return true;
    } catch
    {
        dto = null;
        return false;
    }
}
person Joachim Rosskopf    schedule 07.02.2012