Le ShouldSerialize Pattern, un pattern à (re-)découvrir ? 
Tags: programming, csharp, dotnet, tutorial
Published: 2022-02-13 12:02:35

Le ShouldSerialize Pattern est une fonctionnalité à utiliser dans le contexte de la sérialisation de
données. Malgré tous les avantages que cette fonctionnalité offre, elle demeure méconnue. Dans cet
article, je vous explique comment en tirer parti et dans quel cadre l’utiliser.

Le ShouldSerialize Pattern permet de résoudre facilement des problèmes que j’ai rencontrés à de
nombreuses reprises. Le gain de temps potentiel est donc un aspect à ne pas négliger. Afin d’être le
plus concret possible, je vous propose un exemple pratique à partir du postulat suivant :

- J'ai un objet "Personne" à sérialiser en XML. L'objet sérialisé ne doit contenir la date de décès que si elle existe et par conséquent, ne peut pas être égale à la valeur par défaut d'une DateTime (01/01/0001 00:00:00).  Cet objet a la définition suivante :


```
[XmlRoot("personne", Namespace = Namespace)]
public class Personne {
     [XmlAttribute("nom")]
     public string Nom { get; set; }

     [XmlAttribute("prenom")]
     public string Prenom { get; set; }

     [XmlAttribute("age")]
     public int Age { get; set; }

     [XmlAttribute("dateDeNaissance", DataType = "date")]
     public DateTime DateDeNaissance { get; set; }

     [XmlAttribute("dateDeDeces", DataType = "date")]
     public DateTime DateDeDeces { get; set; }
}
```

Relativement difficile à résoudre avec une DateTime non-nullable, le pattern ShouldSerialize rend la tâche triviale. 

Comment fonctionne-t-il et comment le mettre en place ? 

On n'a besoin que d'une chose : une méthode facultative (apparue très rapidement dans les premières versions .Net et semi cachée dans la documentation officielle, d'où le fait sans doute de sa disparition dans les bonnes pratiques de développement) liée aux propriétés et qui permet d'avertir le concepteur, Visual Studio dans mon cas, que la propriété a été modifiée par rapport à sa valeur par défaut et qu'il doit en tenir compte, ou non, lors de la sérialisation. 

Reprenons notre objet, dans lequel j'implémente la méthode ShouldSerialize{nom de la propriété}() afin de réaliser la demande business :


```
[XmlRoot("personne", Namespace = Namespace)]
public class Personne {
     ...

     [XmlAttribute("dateDeDeces", DataType = "date")]
     public DateTime DateDeDeces { get; set; }
     
     public bool ShouldSerializeDateDeDeces()
     {
         return DateDeDeces != DateTime.MinValue;
     }
}
```
 

Une variante plus récente à partir de C# 7.1, moins lisible à mon sens du fait de l'utilisation du littéral "default", mais renforce la maintenabilité du code : 


```
[XmlRoot("personne", Namespace = Namespace)]
public class Personne {
     ...

     [XmlAttribute("dateDeDeces", DataType = "date")]
     public DateTime DateDeDeces { get; set; }
     
     public bool ShouldSerializeDateDeDeces => DateDeDeces != default;
}
```

Le littéral "default" permet de spécifier la valeur par défaut (merci La Palice) d'un type donné, lorsque le compilateur peut déduire le type d'expression. Dans ce cas, default = DateTime.MinValue. 

Très important dans les deux cas, le nom de la méthode doit commencer par "ShouldSerialize" et être suivi du nom de la propriété visée, "DateDeDeces".

Au moment où la sérialisation XML sera exécutée, la méthode ShouldSerializeDateDeDeces() sera évaluée par le concepteur, si le retour est "true", la propriété sera intégrée dans l'XML résultant, si le retour est "false", elle ne le sera pas.

Les avantages de ce pattern sont :
- Sa facilité d'utilisation, d'écriture et de maintenance sur l'ensemble des propriétés d'un objet à sérialiser, en fonction des demandes business (on sait tous que certaines demandes business peuvent être farfelues ou dépendantes de systèmes rigides et historiques).
- Sa compatibilité pour la plupart des Serializers (XML, JSON, ...).

Vous l'avez compris, si votre projet requiert de la sérialisation, le ShouldSerialize Pattern doit figurer en bonne place parmi votre arsenal de fonctionnalités. Par conséquent, gardez bien cette fonctionnalité dans un coin de votre tête ! Il existe d'autres patterns / fonctionnalités que je vous invite à explorer afin de résoudre le plus efficacement possible vos problèmes liés à la sérialisation de données.

Happy coding !