Blog Stats
  • Posts - 16
  • Articles - 0
  • Comments - 123
  • Trackbacks - 31

 

venerdì 13 luglio 2007

[70-553] – 1. Section 1 – 3 Implementing serialization – 1 – Serialize or deserialize

Rimettiamoci a studiare dopo un po’ di vacanza e un po’ di eccessivo lavoro (tanto per bilanciare).

 

Serialize or deserialize an object or an object graph using runtime serialization techniques (System.Runtime.Serialization namespace)

Le interfacce di serializzazione permettono di controllare tutto il processo e per implementarle è necessario implementare l’interfaccia ISerializable,  che espone il metodo GetObjectData in cui viene effettuato il lavoro.

Ci provo:

    [Serializable]                //senza questo non va nulla

    public class mioOggetto : ISerializable, IEquatable<mioOggetto >

    {  private string nome;

        private string cognome;

        public mioOggetto(string n, string c)

        {

            nome = n;

            cognome = c;

        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)

        {

            info.AddValue("AttributoNome", nome);

            info.AddValue("AttributoCognome", cognome);    

        }

 

        #region IEquatable<mioOggetto> Members

        public bool Equals(mioOggetto obj2)

        {

            if (obj2.nome == nome && obj2.cognome == cognome )              return true;

            else  return false;

        }

        #endregion

     }

 

Per la serializzazione ho bisogno di un oggetto che implementa l’interfaccia IFormatter, per esempio System.Runtime.Serialization.Formatters.Soap.SoapFormatter , e anche di uno stream cosi’ me lo salvo su disco e controllo il risultato.

       static void Main(string[] args)

        {

            mioOggetto obj1 = new mioOggetto("Donald","Duck");

            mioOggetto obj2 = new mioOggetto("Mickey","Mouse");

 

            IFormatter fmt = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();

            System.IO.Stream stream = new System.IO.FileStream("c:\\temp\\testSerialize.xml", System.IO.FileMode.OpenOrCreate   );

            fmt.Serialize( stream, obj1);

            fmt.Serialize( stream, obj2);

            stream.Close();

}

 

Il risultato è un file file xml..cosi’:

<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" …….. /">

<SOAP-ENV:Body>

<a1:mioOggetto id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Test3/Test3%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">

<AttributoNome id="ref-3">Donald</AttributoNome>

<AttributoCognome id="ref-4">Duck</AttributoCognome>

</a1:mioOggetto>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>

<SOAP-ENV:……..

 

Per  deserializzare  il gioco è praticamente identico.. ho bisogno di un altro SoapFormatter e gli dico di deserializzare, aggiungo al mio main le seguenti righe...

      IFormatter fmt2 = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();

      System.IO.Stream stream2 = new System.IO.FileStream("c:\\temp\\testSerialize.xml", System.IO.FileMode.Open    );

      mioOggetto  ret1 = (mioOggetto) fmt2.Deserialize(stream2);

      mioOggetto  ret2 = (mioOggetto) fmt2.Deserialize(stream2);

 

      if (ret1.Equals( obj1) )       Console.Write("Bene.");

      if (ret2.Equals( obj2) )       Console.Write("..bene!");

 

Ma attenzione, il gioco non è finito, se si prova il tutto cosi’ la funzione Deserialize si imbufalisce perchè dice che non ha il costruttore adeguato per la classe. La soluzione? Ovvia, quando la si è scoperta: aggiungere il costruttore  che prende gli stessi parametri della GetObjectData e fa il lavoro inverso. Cosi’:

       public mioOggetto( SerializationInfo info,  StreamingContext cnt)

        {

            nome = info.GetString ("AttributoNome") ;

            cognome = info.GetString ("AttributoCognome");

        }

 

Ci sono altre interfacce per controllare la serializzazione:

IDeserializationCallback: indica la classe deve essere richiamata quando la deserializzazione dell’intero insieme degli oggetti è completata.

IFormatterConverter: fornisce la connessione fra SerializationInfo e la classe formatter, in genere utilizzata per fare il parsing dei dati all’interno delle Info.

IObjectReference: indica che la classe è il riferimento ad un altro oggetto

ISerializationSurrogate: utilizzata per permettere ad un oggetto di effettuare la serializzazione di altri, magari logicamente dipendenti.

 

 

 

Copyright © Bruna Gavioli