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


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

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

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

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

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

  1. Найдите все сведения об использовании BinaryFormatter.
  2. Убедитесь, что serialization пути кода рассматриваются с помощью тестов, чтобы проверить изменения и избежать ошибок.
  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. Замените использование BinaryFormatter ProtoBuf.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; }
}