Delen via


Migreren naar protobuf-net (binair)

De protobuf-net--bibliotheek is een op contracten gebaseerde serialisatiefunctie voor .NET die gebruikmaakt van de binaire Protocolbuffers serialisatie-indeling. De API volgt typische .NET-patronen en is breed vergelijkbaar met XmlSerializer en DataContractSerializer.

Sommige gedragingen en functies van protobuf-net zijn opmerkelijk tijdens migraties van BinaryFormatteren veel scenario's vereisen het toepassen van kenmerken op leden.

  • Openbare en niet-openbare typen zijn standaard serialiseerbaar, waarbij de serializer een parameterloze constructor verwacht.
  • protobuf-net vereist dat elk serializeerbaar type wordt geannoteerd met [ProtoContract] kenmerk. Dit kenmerk kan eventueel de SkipConstructor = true eigenschap opgeven, waardoor de noodzaak van een bepaalde constructor wordt verwijderd .
  • Elk serialiseerbare niet-statisch veld en een eigenschap moeten worden voorzien van aantekeningen met [ProtoMember(int identifier)] kenmerk. De ledennamen worden niet gecodeerd in de gegevens. In plaats daarvan moeten de gebruikers een positief geheel getal kiezen om elk lid te identificeren dat uniek moet zijn binnen dat type.
  • Overname moet expliciet worden gedeclareerd via [ProtoInclude(...)] een kenmerk voor elk type met bekende subtypen.
  • Alleen-lezenvelden worden standaard ondersteund.
  • Als alternatief worden sommige niet-toegeschreven tuple-achtige typen herkend door constructorpatroon. Een type met een constructor met parameters die overeenkomen met (op naam) alle gedeclareerde openbare leden worden geïnterpreteerd als een tuple en de parametervolgorde wordt gebruikt om de id voor dat lid af te leiden.
  • Het gebruik van het protobuf-net.BuildTools ontwerptijdpakket wordt ten zeerste aanbevolen; dit biedt compilatietijdwaarschuwingen van veelvoorkomende fouten.

Stapsgewijze migratie

  1. Zoek alle gebruiksgegevens van BinaryFormatter.
  2. Zorg ervoor dat de serialisatiecodepaden worden behandeld met tests, zodat u uw wijzigingen kunt controleren en fouten kunt voorkomen.
  3. Installeer protobuf-net het pakket (en optioneel protobuf-net.BuildTools).
  4. Zoek alle typen waarmee wordt geserialiseerd BinaryFormatter.
  5. Voor typen die u kunt wijzigen:
    • Aantekeningen maken met [ProtoContract] kenmerk alle typen die zijn gemarkeerd met [Serializable] of implementeren van de ISerializable interface. Als deze typen niet beschikbaar zijn voor andere apps (bijvoorbeeld: u schrijft een bibliotheek) die verschillende serializers kan gebruiken, kunt DataContractSerializeru de [Serializable] en ISerializable aantekeningen verwijderen.
    • Voor afgeleide typen geldt u voor [ProtoInclude(...)] de basistypen (zie het onderstaande voorbeeld).
    • Voor elk type dat een constructor declareert die parameters accepteert, voegt u een parameterloze constructor toe of geeft u SkipConstructor = true het kenmerk op [ProtoContract] . Laat een opmerking achter met de uitleg van de protobuf-net vereiste (zodat niemand het per ongeluk verwijdert).
    • Markeer alle leden (velden en eigenschappen) waarmee u wilt serialiseren [ProtoMember(int identifier)]. Alle id's moeten uniek zijn binnen één type, maar dezelfde getallen kunnen opnieuw worden gebruikt in subtypen als overname is ingeschakeld.
  6. Voor typen die u niet kunt wijzigen:
    • Voor typen die door .NET zelf worden geleverd, kunt u api gebruiken ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type) om te controleren of ze systeemeigen worden ondersteund door protobuf-net.
    • U kunt toegewezen gegevensoverdrachtobjecten (DTO) maken en ze dienovereenkomstig toewijzen (u kunt hiervoor impliciete cast-operator gebruiken).
    • Gebruik de RuntimeTypeModel API om alles te definiëren waarvoor de kenmerken zijn toegestaan.
  7. Vervang het gebruik door 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; }
}