Angella Andrea - Italian Blog

Infinita passione per lo sviluppo software !
posts - 133, comments - 216, trackbacks - 9

My Links

News

MIT OpenCourseWare: I'm invested Wikipedia Affiliate Button


Sto leggendo:

Archives

Post Categories

Siti web realizzati

Siti web tecnici

[70-536] - Serialization and Deserialization

Area di riferimento

- Implementing serialization and input/output functionality in a .NET Framework application (18 percent)
    - Serialize or deserialize an object or an object graph by using runtime serialization techniques.
        - May include but is not limited to: Serialization interfaces; Serialization attributes; SerializationEntry structure and SerializationInfo class;
        - ObjectManager class; Formatter class, FormatterConverter class, and FormatterServices class; StreamingContext structure
   - Control the serialization of an object into XML format by using the System.Xml.Serialization namespace.
       - May include but is not limited to: Serialize and deserialize objects into XML format by using the XmlSerializer class; Control serialization by using serialization attributes;
       - Implement XML serialization interfaces to provide custom formatting for XML serialization; Delegates and event handlers provided by the System.Xml.Serialization namespace 
   - Implement custom serialization formatting by using the Serialization Formatter classes. 
       - May include but is not limited to: SoapFormatter; BinaryFormatter class


Serialization and Deserialization

La serializzazione consiste nel trasformare un oggetto in una sequenza di byte che può essere memorizzata o trasferita tra diverse applicazioni.

Affinchè un tipo possa essere serializzato è necessario decorarlo con l'attributo [Serializable]. Se non non si vuole serializzare un particolare membro allora si utilizza l'attributo [NonSerialized]. Nel caso fosse necessario eseguire del codice dopo l'operazione di deserializzazione (per esempio per impostare membri calcolati che non sono stati serializzati) si può implementare l'interfaccia IDeserializationCallback come mostrato nell'esempio.

1 [Serializable] 2 class Student : IDeserializationCallback 3 { 4 public Student(string name, string surname, DateTime birthDate) 5 { 6 Name = name; 7 Surname = surname; 8 BirthDate = birthDate; 9 calculateAge(); 10 } 11 12 public string Name { get; set; } 13 public string Surname { get; set; } 14 public DateTime BirthDate { get; set; } 15 16 [NonSerialized] 17 [SoapIgnore] 18 private int age; 19 20 public int Age 21 { 22 get 23 { 24 return age; 25 } 26 set 27 { 28 age = value; 29 } 30 } 31 32 public override string ToString() 33 { 34 return Name + ", " + Surname + ", " + BirthDate.ToShortDateString() + ", " + age; 35 } 36 37 private void calculateAge() 38 { 39 Age = DateTime.Now.Year - BirthDate.Year; 40 } 41 42 public void OnDeserialization(object sender) 43 { 44 calculateAge(); 45 } 46 }


Con la classe BinaryFormatter è possibile serializzare in modo efficiente l'oggetto ma questo sarà accessibile solo da parte di altre applicazioni .NET:

static void Main(string[] args) { Student student = new Student("Andrea", "Angella", new DateTime(1984, 7, 14)); // Binary Serialization using (FileStream fs = new FileStream("file.dat", FileMode.Create)) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, student); } // Binary Deserialization using (FileStream fs = new FileStream("file.dat", FileMode.Open)) { BinaryFormatter bf = new BinaryFormatter(); student = (Student)bf.Deserialize(fs); } Console.Write(student); Console.ReadKey(); }

 

La classe SoapFormatter (assembly System.Runtime.Serialization.Formatters.Soap) permette di serializzare un oggetto come un SOAP Envelop adatto per essere condiviso anche con applicazioni non appartenenti al mondo .NET. Il suo utilizzo è analogo a quello della classe BinaryFormatter. E' possibile controllare la formattazione utilizzando opportuni attributi come [SoapAttribute], [SoapElement], [SoapEnum], [SoapIgnore] e [SoapInclude].

E' possibile serializzare un oggetto in uno specifico formato XML attraverso la classe XmlSerializer. Questa modalità ovviamente porta con se i vantaggi del linguaggio XML e cioè forte interoperabilità, amministrazione user-friendly e migliore compatibilità all'indietro. La serializzazione XML può serializzare solamente membri pubblici (al contrario di quella binaria) e non possono essere serializzati grafi di oggetti. E' richiesto un costruttore di default. Anche in questo caso è possibile personalizzare il markup xml che sarà generato utilizzando opportuni attributi come [XmlAttribute], [XmlElement], [XmlIgnore], [XmlEnum] ecc.

E' interessante la possibiiltà di generare classi con attributi xml a partire da un file XML Schema Definition. Lo strumento da utilizzare è il tool a linea di comando xsd.

Se si vuole avere un controllo maggiore sul processo di serializzazione e deserializzazione è possibile implementare l'interfaccia ISerializable. Tramite il metodo GetObjectData si specificano i membri che si vogliono serializzare. All'interno di un particolare costruttore (chiamato dopo la fase di deserializzazione) sarà possibile accedere a questi valori e ripristinare il contenuto dell'oggetto. E' possibile intervenire prima e dopo la fase di serializzazione e deserializzazione inserendo opportuni metodi decorati con gli attributi [OnSerializing], [OnSerialized], [OnDeserializing], [OnDeserialized]. La classe StreamingContext è utile se si vuole serializzare un oggetto in modo differente in base alla destinazione (stesso processo, processi su macchine differenti, ecc. ).

[Serializable] public class Student : ISerializable { public string Name { get; set; } public string Surname { get; set; } public DateTime BirthDate { get; set; } public int Age { get; set; } // Costruttore standard public Student(string name, string surname, DateTime birthDate) { Name = name; Surname = surname; BirthDate = birthDate; calculateAge(); } // Costruttore per la deserializzazione public Student(SerializationInfo info, StreamingContext context) { Name = info.GetString("Name"); Surname = info.GetString("Surname"); BirthDate = info.GetDateTime("BirthDate"); } [OnSerializing] void BeforeSerialization(StreamingContext context) { // ... } [OnSerialized] void AfterSerialization(StreamingContext context) { // ... } [OnDeserializing] void BeforeDeserialization(StreamingContext context) { // ... } [OnDeserialized] void AfterDeserialization(StreamingContext context) { calculateAge(); } public override string ToString() { return Name + ", " + Surname + ", " + BirthDate.ToShortDateString() + ", " + Age; } private void calculateAge() { Age = DateTime.Now.Year - BirthDate.Year; } #region ISerializable Members // Metodo chiamato durante la fase di serializzazione public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Name", Name); info.AddValue("Surname", Surname); info.AddValue("BirthDate", BirthDate); } #endregion }


Anche se è raramente necessario è bene sapere che è offerta anche la possibilità di realizzare dei formatter personalizzati. Invece di utilizzare ad esempio la classe BinaryFormatter è possibile costruire il proprio formatter implementando l'interfaccia IFormatter o IGenericFormatter

Print | posted on domenica 2 novembre 2008 01:59 | Filed Under [ Exam 70-536 Application Development Foundation ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET