Migrer vers protobuf-net (binaire)
La bibliothèque protobuf-net est un sérialiseur basé sur contrat pour .NET qui utilise le format binaire des mémoires tampons de protocoleserialization. L’API suit des modèles .NET classiques, et est globalement comparable à XmlSerializer
et DataContractSerializer
.
Certains comportements et fonctionnalités de protobuf-net seront notables lors des migrations à partir de BinaryFormatter, et de nombreux scénarios nécessitent l’application d’attributs aux membres.
- Par défaut, les types publics et non publics sont sérialisables, le sérialiseur attendant un constructeur sans paramètre.
- protobuf-net nécessite que chaque type sérialisable soit annoté avec un attribut
[ProtoContract]
; cet attribut peut éventuellement spécifier la propriétéSkipConstructor = true
, ce qui supprime la nécessité d’un constructeur particulier. - Chaque champ non statique sérialisable et propriété doit être annotée avec un attribut
[ProtoMember(int identifier)]
. Les noms des membres ne sont pas encodés dans les données. Au lieu de cela, les utilisateurs doivent choisir un entier positif pour identifier chaque membre, qui doit être unique au sein de ce type. - L’héritage doit être explicitement déclaré via l’attribut
[ProtoInclude(...)]
sur chaque type avec des sous-types connus. - Les champs en lecture seule sont pris en charge par défaut.
- Par ailleurs, certains types tuples non attribués sont reconnus par le modèle de constructeur ; un type avec un constructeur qui a des paramètres qui correspondent (par nom) à tous les membres publics déclarés sera interprété comme un tuple, et l’ordre des paramètres sera utilisé pour déduire l’identificateur de ce membre.
- L’utilisation du package au moment du design
protobuf-net.BuildTools
est vivement recommandée. Cela offre des avertissements au moment de la compilation concernant les erreurs courantes.
Migration pas à pas
- Recherchez toutes les utilisations de
BinaryFormatter
. - Assurez-vous que les chemins d’accès au code serialization sont couverts par des tests, pour pouvoir vérifier vos modifications et éviter l'introduction de bogues.
- Installez le package
protobuf-net
(et éventuellementprotobuf-net.BuildTools
). - Recherchez tous les types sérialisés avec
BinaryFormatter
. - Pour les types que vous pouvez modifier :
- Annotez avec l’attribut
[ProtoContract]
tous les types marqués avec[Serializable]
, ou implémentez l’interfaceISerializable
. Si ces types ne sont pas exposés à d’autres applications (par exemple, si vous écrivez une bibliothèque) susceptibles d’utiliser différents sérialiseurs commeDataContractSerializer
, vous pouvez supprimer les annotations[Serializable]
etISerializable
. - Pour les types dérivés, appliquez
[ProtoInclude(...)]
à leurs types de base (voir l’exemple ci-dessous). - Pour chaque type qui déclare tout constructeur qui accepte des paramètres, ajoutez un constructeur sans paramètre ou spécifiez
SkipConstructor = true
sur l’attribut[ProtoContract]
. Laissez un commentaire qui explique l’exigence relative à protobuf-net (afin que personne ne le supprime par accident). - Marquez tous les membres (champs et propriétés) que vous souhaitez sérialiser avec
[ProtoMember(int identifier)]
. Tous les identificateurs doivent être uniques au sein d’un type, mais les mêmes nombres peuvent être réutilisés dans les sous-types si l’héritage est activé.
- Annotez avec l’attribut
- Pour les types que vous ne pouvez pas modifier :
- Pour les types fournis par .NET lui-même, vous pouvez utiliser l’API
ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type)
pour vérifier s’ils sont pris en charge en mode natif par protobuf-net. - Vous pouvez créer des objets de transfert de données (DTO) dédiés et les mapper en conséquence (vous pouvez utiliser l’opérateur de cast implicite pour cela).
- Utilisez l’API
RuntimeTypeModel
pour définir tout ce que les attributs autorisent.
- Pour les types fournis par .NET lui-même, vous pouvez utiliser l’API
- Remplacez l’utilisation de
BinaryFormatter
parProtoBuf.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; }
}
Collaborer avec nous sur GitHub
La source de ce contenu se trouve sur GitHub, où vous pouvez également créer et examiner les problèmes et les demandes de tirage. Pour plus d’informations, consultez notre guide du contributeur.