Поделиться через


Миграция на protobuf-net (binary)

Библиотека protobuf-net — это сериализатор на основе контракта для .NET, использующий двоичный формат сериализации Protocol Buffers . API следует типичным шаблонам .NET и в целом сравним с XmlSerializer и DataContractSerializer.

Некоторые поведения и функции protobuf-net будут заметными во время миграции из BinaryFormatter, и многие сценарии требуют применения атрибутов к элементам.

  • По умолчанию как общедоступные, так и не открытые типы сериализуются, при этом сериализатор ожидает конструктора без параметров.
  • Protobuf-net требует, чтобы каждый сериализуемый тип был аннотирован с [ProtoContract] атрибутом. Этот атрибут может при необходимости указать SkipConstructor = true свойство, которое удаляет необходимость в любом конкретном конструкторе.
  • Каждое сериализуемое нестатическое поле и свойство должно быть аннотировано атрибутом [ProtoMember(int identifier)] . Имена членов не кодируются в данных. Вместо этого пользователи должны выбрать положительное целое число, чтобы определить каждый элемент, который должен быть уникальным в этом типе.
  • Наследование должно быть явно объявлено с помощью [ProtoInclude(...)] атрибута для каждого типа с известными подтипами.
  • Поля только для чтения поддерживаются по умолчанию.
  • Кроме того, некоторые ненаписанные типы кортежей распознаются шаблоном конструктора; тип с конструктором, который имеет параметры, соответствующие (по имени), все объявленные общедоступные элементы будут интерпретированы как кортеж, и порядок параметров будет использоваться для вывода идентификатора этого элемента.
  • Использование пакета времени разработки protobuf-net.BuildTools настоятельно рекомендуется. Это предлагает предупреждения во время компиляции распространенных ошибок.

Пошаговая миграция

  1. Найдите все сведения об использовании BinaryFormatter.
  2. Убедитесь, что пути кода сериализации рассматриваются тестами, поэтому вы можете проверить изменения и избежать возникновения ошибок.
  3. Установите protobuf-net пакет (и необязательно protobuf-net.BuildTools).
  4. Найдите все типы, сериализованные с BinaryFormatterпомощью .
  5. Для типов, которые можно изменить:
    • Заметите атрибутом [ProtoContract] все типы, помеченные или [Serializable] реализующие ISerializable интерфейс. Если эти типы не предоставляются другим приложениям (например, вы пишете библиотеку), которые могут использовать различные сериализаторы, например DataContractSerializer, можно удалить [Serializable] и ISerializable заметки.
    • Для производных типов применяются [ProtoInclude(...)] к их базовым типам (см. приведенный ниже пример).
    • Для каждого типа, объявляющего любой конструктор, принимаюющий параметры, добавьте конструктор без параметров или укажите SkipConstructor = true для атрибута [ProtoContract] . Оставьте комментарий, который объясняет требование protobuf-net (так что никто не удаляет его случайно).
    • Пометьте все элементы (поля и свойства), с которыми вы хотите сериализовать [ProtoMember(int identifier)]. Все идентификаторы должны быть уникальными в пределах одного типа, но одни и те же числа можно повторно использовать в подтипах, если наследование включено.
  6. Для типов, которые нельзя изменить:
    • Для типов, предоставляемых самим .NET, можно использовать ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type) API для проверки того, поддерживаются ли они в собственном коде protobuf-net.
    • Вы можете создать выделенные объекты передачи данных (DTO) и сопоставить их соответствующим образом (для этого можно использовать неявный оператор приведения).
    • RuntimeTypeModel Используйте API для определения всех разрешенных атрибутов.
  7. Замените использование BinaryFormatterProtoBuf.Serializer.
-[Serializable]
+[ProtoContract]
+[ProtoInclude(2, typeof(Point2D))]
public class Point1D
{
+   [ProtoMember(1)]
    public int X { get; set; }
}

-[Serializable]
+[ProtoContract]
public class Point2D : Point1D
{
+   [ProtoMember(2)]
    public int Y { get; set; }
}