Compartilhar via


Migrar para protobuf-net (binário)

A protobuf-net é uma biblioteca baseada em contrato para .NET que usa o formato de Buffers de Protocoloserialization binário. A API segue padrões típicos do .NET e é amplamente comparável a XmlSerializer e DataContractSerializer.

Alguns comportamentos e recursos do protobuf-net serão notáveis durante as migrações de BinaryFormatter, e muitos cenários exigem a aplicação de atributos aos membros.

  • Por padrão, os tipos públicos e não públicos são serializáveis, com o serializador esperando um construtor sem parâmetros.
  • protobuf-net requer que cada tipo serializável seja anotado com [ProtoContract] atributo; esse atributo pode, opcionalmente, especificar a propriedade SkipConstructor = true, o que remove a necessidade de qualquer construtor específico.
  • Cada campo não estático serializável e uma propriedade precisam ser anotados com [ProtoMember(int identifier)] atributo. Os nomes de membro não são codificados nos dados. Em vez disso, os usuários devem escolher um inteiro positivo para identificar cada membro que deve ser exclusivo dentro desse tipo.
  • A Herança deve ser declarada explicitamente por meio do atributo [ProtoInclude(...)] em cada tipo com subtipos conhecidos.
  • Os campos somente leitura têm suporte por padrão.
  • Como alternativa, alguns tipos de tupla não atribuídos são reconhecidos pelo padrão de construtor; um tipo com um construtor que tem parâmetros que correspondem (por nome), todos os membros públicos declarados serão interpretados como uma tupla e a ordem de parâmetro será usada para inferir o identificador desse membro.
  • O uso do pacote de tempo de design protobuf-net.BuildTools é altamente recomendado; isso oferece avisos de tempo de compilação de erros comuns.

Migração passo a passo

  1. Encontre todos os usos de BinaryFormatter.
  2. Certifique-se de que os caminhos de serialization código sejam cobertos com testes, para que você possa verificar suas alterações e evitar a introdução de bugs.
  3. Instalar o pacote protobuf-net (e, opcionalmente protobuf-net.BuildTools).
  4. Encontre todos os tipos que estão sendo serializados com BinaryFormatter.
  5. Para tipos que você pode modificar:
    • Anotar com [ProtoContract] atributo todos os tipos marcados com [Serializable] ou implementar a interface ISerializable. Se esses tipos não forem expostos a outros aplicativos (exemplo: você está escrevendo uma biblioteca) que pode usar serializadores diferentes, como DataContractSerializer, você poderá remover as anotações [Serializable] e ISerializable.
    • Para tipos derivados, aplique [ProtoInclude(...)] a seus tipos base (consulte o exemplo abaixo).
    • Para cada tipo que declara qualquer construtor que aceite parâmetros, adicione um construtor sem parâmetros ou especifique SkipConstructor = true no atributo [ProtoContract]. Deixe um comentário que explique o requisito protobuf-net (para que ninguém o remova por acidente).
    • Marque todos os membros (campos e propriedades) que você deseja serializar com [ProtoMember(int identifier)]. Todos os identificadores devem ser exclusivos em um único tipo, mas os mesmos números poderão ser reutilizados em subtipos se a herança estiver habilitada.
  6. Para tipos que você não pode modificar:
    • Para tipos fornecidos pelo próprio .NET, você pode usar ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type) API para verificar se eles têm suporte nativo pelo protobuf-net.
    • Você pode criar objetos de transferência de dados dedicados (DTO) e mapeá-los adequadamente (você pode usar o operador de conversão implícita para isso).
    • Use a API RuntimeTypeModel para definir tudo o que os atributos permitem.
  7. Substitua o uso de BinaryFormatter por 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; }
}