// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
//                         marc.chevaldonne.free.fr
//
// Module        : Program.cs
// Author        : Marc Chevaldonné
// Creation date : 2016-10-06
//
// ========================================================================

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace ex_038_003_DataContract_ObjectReferences
{
    class Program
    {
        static void Main(string[] args)
        {
            Directory.SetCurrentDirectory(Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "ex_038_003_DataContract_ObjectReferences", "XML"));

            //on crée la structure suivante :
            //Morceau(bulgarska) --compositeur--> Artiste(Bojan Z)
            //                   --album--------> Album (Duo) --Artiste1--> Artiste(BojanZ)
            //                                                --Artiste2--> Artiste(Julien Lourau)
            //On va persister Morceau. On voit donc ici que la sérialisation de Morceau va entrainer la sérialisation d'un artiste (le compositeur), 
            //  et d'un Album qui va entrainer la sérialisation de deux artistes (Bojan Z et Julien Lourau).
            //L'Artiste Bojan Z va donc être sérialisé deux fois dans le même fichier. C'est ce qu'on veut éviter.
            //
            //Dans la 1ère partie de l'exemple, la sérialisation ne gère pas les références d'objets.
            //Cela sera fait dans la 2ème partie.

            //création des instances d'Artiste, Album et Morceau
            Artiste bojan = new Artiste { Prénom = "Bojan", Nom = "Z", Naissance = new DateTime(1968, 2, 2), Instrument = "Piano" };
            Artiste julien = new Artiste { Prénom = "Julien", Nom = "Lourau", Naissance = new DateTime(1970, 1, 1), Instrument = "Saxophone" };

            Album duo = new Album { Titre = "Duo", AnnéeDeSortie = 2015, Artiste1 = bojan, Artiste2 = julien };

            Morceau bulgarska = new Morceau { Titre = "Bulgarska", Album = duo, Compositeur = bojan };

            //--1-- pas de gestion des références d'objets
            //création du sérialiseur en n'indiquant que le type d'objet à sérialiser (ici Morceau)
            var serializer = new DataContractSerializer(typeof(Morceau));

            //sérialisation
            XmlWriterSettings settings = new XmlWriterSettings() { Indent = true };
            using (TextWriter tw = File.CreateText("bulgarska.xml"))
            using (XmlWriter writer = XmlWriter.Create(tw, settings))
            {
                serializer.WriteObject(writer, bulgarska);
            }
            //observez le fichier bulgarska.xml pour constater que l'Artiste Bojan Z est sérialisé deux fois.
            // on voit notamment deux fois le fragment XML suivant :
            // <Prénom>Bojan</Prénom>
            // <Nom>Z</Nom>
            // <Naissance>1968-02-02T00:00:00</Naissance>
            // <Instrument>Piano</Instrument>


            //--2-- gestion des références d'objets
            //création du sérialiseur
            //dans cette version du constructeur, on peut spécifier dans les settings du serializer qu'on veut gérer les références d'objets.
            var serializer2 = new DataContractSerializer(typeof(Morceau), new DataContractSerializerSettings() { PreserveObjectReferences=true });
             
            //sérialisation
            using (TextWriter tw = File.CreateText("bulgarska2.xml"))
            using (XmlWriter writer = XmlWriter.Create(tw, settings))
            {
                serializer2.WriteObject(writer, bulgarska);
            }
            //observez le fichier bulgarska2.xml pour constater que l'Artiste Bojan Z n'est sérialisé qu'une fois et qu'on y fait référence par la suite :
            //Forme de la sérialisation (notez la présence des z:Id):
            // <Compositeur z:Id="3">
            //   <Prénom z:Id="4">Bojan</Prénom>
            //   <Nom z:Id="5">Z</Nom>
            //   <Naissance>1968-02-02T00:00:00</Naissance>
            //   <Instrument z:Id="6">Piano</Instrument>
            // </Compositeur>
            //La deuxième fois que l'Artiste aurait dû être sérialisé, il n'y est que fait référence (notez la présence de z:Ref) :
            // <Artiste1 z:Ref="3" i:nil="true"/>
        }
    }
}
