Partager via


Sérialisation

Remarque

Ce contenu est réimprimé avec l’autorisation de Pearson Education, Inc. à partir des Instructions de conception d’une infrastructure : conventions, idiomes et modèles des bibliothèques réutilisables .NET, 2ème édition. Cette édition a été publiée en 2008, et le livre a été entièrement révisé dans la troisième édition. Certaines informations de cette page peuvent être obsolètes.

La sérialisation correspond au processus de conversion d’un objet dans un format facile à rendre persistant ou à transporter. Par exemple, vous pouvez sérialiser un objet, le transporter sur Internet à l’aide du protocole HTTP, puis le désérialiser sur l’ordinateur de destination.

Le .NET Framework propose trois technologies principales de sérialisation optimisées pour différents scénarios de sérialisation. Le tableau suivant liste ces technologies et les principaux types de framework qui leur sont associés.

Nom de technologie Principaux types Scénarios
Sérialisation du contrat de données DataContractAttribute
DataMemberAttribute
DataContractSerializer
NetDataContractSerializer
DataContractJsonSerializer
ISerializable
Persistance générale
Services Web
JSON
Sérialisation XML XmlSerializer Format XML avec contrôle total sur la forme du code XML
Sérialisation du runtime (binaire et SOAP) SerializableAttribute
ISerializable
BinaryFormatter
SoapFormatter
.NET Remoting

✔️ PENSEZ à la sérialisation lorsque vous concevez de nouveaux types.

Sélection de la technologie de sérialisation appropriée à prendre en charge

✔️ ENVISAGEZ de prendre en charge la sérialisation du contrat de données si des instances de votre type doivent être rendues persistantes ou utilisées dans des services web.

✔️ ENVISAGEZ de prendre en charge la sérialisation XML au lieu ou en plus de la sérialisation du contrat de données si vous devez davantage contrôler le format XML généré lors de la sérialisation du type.

Cela peut s’avérer nécessaire dans certains scénarios d’interopérabilité où vous devez utiliser une construction XML qui n’est pas prise en charge par la sérialisation du contrat de données, par exemple, pour générer des attributs XML.

✔️ ENVISAGEZ de prendre en charge la sérialisation du runtime si des instances de votre type ont besoin de franchir des limites .NET Remoting.

❌ ÉVITEZ de prendre en charge la sérialisation XML ou du runtime uniquement pour des raisons de persistance. Préférez plutôt la sérialisation du contrat de données.

Prise en charge de la sérialisation du contrat de données

Les types peuvent prendre en charge la sérialisation du contrat de données en appliquant DataContractAttribute au type et DataMemberAttribute aux membres (champs et propriétés) du type.

✔️ ENVISAGEZ de marquer les membres de données de votre type comme publics si le type peut être utilisé en mode de confiance partielle.

En mode de confiance totale, les sérialiseurs de contrat de données peuvent sérialiser et désérialiser les types et les membres non publics, mais seuls les membres publics peuvent être sérialisés et désérialisés en mode de confiance partielle.

✔️ IMPLÉMENTEZ un getter et un setter sur toutes les propriétés pour lesquelles DataMemberAttribute est défini. Les sérialiseurs de contrat de données nécessitent à la fois le getter et le setter pour que le type soit considéré comme étant sérialisable. (Dans .NET Framework 3.5 SP1, certaines propriétés de collection peuvent être get uniquement.) Si le type ne sera pas utilisé en mode de confiance partielle, l’un des accesseurs de propriété ou les deux peuvent ne pas être publics.

✔️ ENVISAGEZ d’utiliser les rappels de sérialisation pour l’initialisation des instances désérialisées.

Les constructeurs ne sont pas appelés lorsque les objets sont désérialisés. (Il existe des exceptions à la règle. Les constructeurs de collections marquées avec CollectionDataContractAttribute sont appelés pendant la désérialisation.) Par conséquent, toute logique qui s’exécute pendant la construction normale doit être implémentée comme l’un des rappels de sérialisation.

L’attribut OnDeserializedAttribute est l’attribut de rappel le plus communément utilisé. Les autres attributs de la famille sont OnDeserializingAttribute, OnSerializingAttribute et OnSerializedAttribute. Ils peuvent être utilisés pour marquer les rappels exécutés avant la désérialisation, avant la sérialisation et enfin, après la sérialisation, respectivement.

✔️ ENVISAGEZ d’utiliser KnownTypeAttribute pour indiquer les types concrets qui doivent être utilisés lors de la désérialisation d’un graphe d’objets complexes.

✔️ TENEZ COMPTE de la compatibilité ascendante et descendante lors de la création ou modification de types sérialisables.

Gardez à l'esprit que les flux sérialisés de futures versions de votre type peuvent être désérialisés dans la version actuelle du type, et inversement.

Assurez-vous d’avoir bien assimilé que les membres de données, même privés et internes, ne peuvent pas modifier leurs nom, type ou ordre dans les futures versions du type, sauf si vous veillez à conserver le contrat à l’aide de paramètres explicites dans les attributs du contrat de données.

Testez la compatibilité de la sérialisation lorsque vous apportez des modifications aux types sérialisables. Essayez de désérialiser la nouvelle version dans une ancienne version, et inversement.

✔️ ENVISAGEZ d’implémenter IExtensibleDataObject pour permettre l’aller-retour entre les différentes versions du type.

L'interface permet au sérialiseur de garantir qu'aucune donnée n'est perdue lors de l'aller-retour. La propriété IExtensibleDataObject.ExtensionData est utilisée pour stocker toutes les données de la future version du type qui sont inconnues de la version actuelle et elle ne peut donc pas les stocker dans ses membres de données. Lorsque la version actuelle est par la suite sérialisée et désérialisée dans une future version, les données supplémentaires sont disponibles dans le flux sérialisé.

Prise en charge de la sérialisation XML

La sérialisation du contrat de données est la principale technologie de sérialisation (par défaut) dans le .NET Framework. Il existe cependant des scénarios de sérialisation qui ne sont pas pris en charge par cette technologie. Par exemple, vous n'avez pas le contrôle total sur la forme du XML généré ou consommé par le sérialiseur. Si ce contrôle renforcé est nécessaire, vous devez utiliser la sérialisation XML et concevoir vos types pour prendre en charge cette technologie de sérialisation.

❌ ÉVITEZ de concevoir vos types spécifiquement pour la sérialisation XML, sauf si vous avez une bonne raison de contrôler la forme du XML généré. Cette technologie de sérialisation a été remplacée par la sérialisation du contrat de données présentée dans la section précédente.

✔️ ENVISAGEZ d’implémenter l’interface IXmlSerializable si vous souhaitez davantage de contrôle sur la forme du XML sérialisé que celui proposé en appliquant les attributs de sérialisation XML. Deux méthodes de l’interface, ReadXml et WriteXml, vous offrent un contrôle total sur le flux XML sérialisé. Vous pouvez aussi contrôler le schéma XML qui est généré pour le type en appliquant l’attribut XmlSchemaProviderAttribute.

Prise en charge de la sérialisation du runtime

La technologie de sérialisation du runtime est utilisée par .NET Remoting. Si vous pensez que vos types vont être transportés à l’aide de .NET Remoting, assurez-vous qu’ils prennent en charge la sérialisation du runtime.

La prise en charge de base de la sérialisation du runtime peut être fournie en appliquant l’attribut SerializableAttribute. Des scénarios plus avancés nécessitent l’implémentation d’un modèle sérialisable du runtime simple (implémentez ISerializable et fournissez un constructeur de sérialisation).

✔️ ENVISAGEZ de prendre en charge la sérialisation du runtime si vos types vont être utilisés avec .NET Remoting. Par exemple, l’espace de noms System.AddIn utilise .NET Remoting, et par conséquent tous les types échangés entre les compléments System.AddIn ont besoin de prendre en charge la sérialisation du runtime.

✔️ ENVISAGEZ d’implémenter le modèle sérialisable du runtime si vous souhaitez avoir un contrôle total sur le processus de sérialisation. Par exemple, si vous souhaitez transformer des données à mesure qu'elles sont sérialisées ou désérialisées.

Le modèle est très simple. Il suffit d'implémenter l'interface ISerializable et de fournir un constructeur spécial qui est utilisé lorsque l'objet est désérialisé.

✔️ SÉCURISEZ le constructeur de sérialisation et fournissez deux paramètres typés et nommés de la même façon que dans l’exemple indiqué ici.

[Serializable]
public class Person : ISerializable
{
    protected Person(SerializationInfo info, StreamingContext context)
    {
        // ...
    }
}

✔️ IMPLÉMENTEZ explicitement les membres ISerializable.

✔️ APPLIQUEZ une demande de liaison à l’implémentation de ISerializable.GetObjectData. Cela garantit que seuls le code d’un niveau de confiance totale et le sérialiseur du runtime ont accès au membre.

Portions © 2005, 2009 Microsoft Corporation. Tous droits réservés.

Réimprimé avec l’autorisation de Pearson Education, Inc. et extrait de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition par Krzysztof Cwalina et Brad Abrams, publié le 22 octobre 2008 par Addison-Wesley Professional dans le cadre de la série sur le développement Microsoft Windows.

Voir aussi