Partilhar via


Migrar para protobuf-net (binário)

A biblioteca protobuf-net é um serializador baseado em contrato para .NET que usa o formato binário Protocol Buffersserialization . A API segue padrões .NET típicos e é amplamente comparável a XmlSerializer e DataContractSerializer.

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

  • Por padrão, os tipos público e não público 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, este atributo pode opcionalmente especificar a propriedade, o SkipConstructor = true que elimina a necessidade de qualquer construtor em particular.
  • Cada campo não estático serializável e uma propriedade precisam ser anotados com [ProtoMember(int identifier)] atributo. Os nomes dos membros 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 explicitamente declarada via [ProtoInclude(...)] atributo em cada tipo com subtipos conhecidos.
  • Os campos somente leitura são suportados por padrão.
  • Alternativamente, alguns tipos semelhantes a tuplas não atribuídas são reconhecidos pelo padrão do construtor, um tipo com um construtor que tem parâmetros que correspondem (pelo nome) a todos os membros públicos declarados será interpretado como uma tupla, e a ordem dos parâmetros será usada para inferir o identificador para esse membro.
  • O uso do pacote de tempo de protobuf-net.BuildTools design é altamente recomendado, o que oferece avisos em tempo de compilação de erros comuns.

Migração passo a passo

  1. Encontre todos os usos do 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. Instale protobuf-net o pacote (e, opcionalmente protobuf-net.BuildTools).
  4. Encontre todos os tipos que estão sendo serializados com BinaryFormattero .
  5. Para tipos que você pode modificar:
    • Anote com [ProtoContract] atributo todos os tipos marcados com [Serializable] ou implemente a ISerializable interface. Se esses tipos não forem expostos a outros aplicativos (exemplo: você está escrevendo uma biblioteca) que podem usar serializadores diferentes, como DataContractSerializer, você pode remover as [Serializable] anotações e ISerializable .
    • Para tipos derivados, aplique [ProtoInclude(...)] aos seus tipos de base (veja o exemplo abaixo).
    • Para cada tipo que declara qualquer construtor que aceita parâmetros, adicione um construtor sem parâmetros ou especifique SkipConstructor = true no [ProtoContract] atributo. 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 deseja serializar com [ProtoMember(int identifier)]o . Todos os identificadores devem ser exclusivos dentro de um único tipo, mas os mesmos números podem ser reutilizados em subtipos se a herança estiver habilitada.
  6. Para tipos que não podem ser modificados:
    • Para tipos fornecidos pelo próprio .NET, você pode usar ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type) a API para verificar se eles são suportados nativamente pelo protobuf-net.
    • Você pode criar objetos de transferência de dados dedicados (DTO) e mapeá-los de acordo (você pode usar o operador de transmissão implícito para isso).
    • Use a API para definir tudo o RuntimeTypeModel 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; }
}