Может ли сильное именование вызвать проблемы с сериализацией объектов в C #? - PullRequest
3 голосов
/ 19 мая 2009

Я сериализую некоторые объекты конфигурации и сохраняю результирующие байты в базе данных.

new BinaryFormatter().Serialize(memoryStream, instance);
Convert.ToBase64String(memoryStream.ToArray());

Эти объекты будут десериализованы позже.

new BinaryFormatter().Deserialize(memoryStream);

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

Спасибо за помощь

Ответы [ 2 ]

2 голосов
/ 19 мая 2009

Абсолютно, использование BinaryFormatter с базой данных (т.е. долгосрочным) хранилищем является плохой идеей; BinaryFormatter имеет два три больших сбоя (по умолчанию):

  • включает метаданные типа (если вы перемещаете / переименовываете ваши типы ... это может означать строгое имя / контроль версий)
  • включает имена полей (поля являются частными!)
  • это специфично для .NET (что будет неприятно, если вы когда-нибудь захотите использовать что-либо еще)

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

Я рекомендую использовать сериализацию на основе контракта. XmlSerializer или DataContractSerializer вполне достаточно. Если вам нужен небольшой эффективный двоичный файл, тогда protobuf-net может быть интересен. В отличие от BinaryFormatter, двоичный файл этого кода переносим между реализациями, расширяем (для новых полей) и т. Д. И он на быстрее и меньше .

0 голосов
/ 19 мая 2009

Я думаю, что WCF может быть вашим лучшим выбором. Он может обрабатывать передачу неизвестных полей своему потребителю, даже если он не знает, как их десериализовать.

Пример:

Служба A: знает о версии 2 класса Widget, который имеет поле описания

Служба B: знает о версии 1 класса Widget, который не имеет поля Description

Служба C: знает о версии 2 класса Widget, который имеет поле описания

Если служба A вызывает службу B, передающую объект Widget, а затем служба B вызывает службу C, передающую тот же объект Widget, тогда служба C получит поле Description, как оно было передано из службы A. Служба B не будет иметь никакого описания. поле, но когда оно десериализует его и повторно сериализует, оно просто пропустит поле Описание, не зная, что это такое.

Таким образом, вы можете использовать службы WCF с внутрипроцессным взаимодействием.

См. Эту ссылку для получения дополнительной информации о версиях контрактов wcf .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...