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:

1 static void Main(string[] args) 2 { 3 Student student = new Student("Andrea", "Angella", new DateTime(1984, 7, 14)); 4 5 // Binary Serialization 6 using (FileStream fs = new FileStream("file.dat", FileMode.Create)) 7 { 8 BinaryFormatter bf = new BinaryFormatter(); 9 bf.Serialize(fs, student); 10 } 11 12 // Binary Deserialization 13 using (FileStream fs = new FileStream("file.dat", FileMode.Open)) 14 { 15 BinaryFormatter bf = new BinaryFormatter(); 16 student = (Student)bf.Deserialize(fs); 17 } 18 19 Console.Write(student); 20 Console.ReadKey(); 21 }

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. ).

1 [Serializable] 2 public class Student : ISerializable 3 { 4 public string Name { get; set; } 5 public string Surname { get; set; } 6 public DateTime BirthDate { get; set; } 7 public int Age { get; set; } 8 9 // Costruttore standard 10 public Student(string name, string surname, DateTime birthDate) 11 { 12 Name = name; 13 Surname = surname; 14 BirthDate = birthDate; 15 calculateAge(); 16 } 17 18 // Costruttore per la deserializzazione 19 public Student(SerializationInfo info, StreamingContext context) 20 { 21 Name = info.GetString("Name"); 22 Surname = info.GetString("Surname"); 23 BirthDate = info.GetDateTime("BirthDate"); 24 } 25 26 [OnSerializing] 27 void BeforeSerialization(StreamingContext context) 28 { 29 // ... 30 } 31 32 [OnSerialized] 33 void AfterSerialization(StreamingContext context) 34 { 35 // ... 36 } 37 38 [OnDeserializing] 39 void BeforeDeserialization(StreamingContext context) 40 { 41 // ... 42 } 43 44 [OnDeserialized] 45 void AfterDeserialization(StreamingContext context) 46 { 47 calculateAge(); 48 } 49 50 public override string ToString() 51 { 52 return Name + ", " + Surname + ", " + BirthDate.ToShortDateString() + ", " + Age; 53 } 54 55 private void calculateAge() 56 { 57 Age = DateTime.Now.Year - BirthDate.Year; 58 } 59 60 #region ISerializable Members 61 62 // Metodo chiamato durante la fase di serializzazione 63 public void GetObjectData(SerializationInfo info, StreamingContext context) 64 { 65 info.AddValue("Name", Name); 66 info.AddValue("Surname", Surname); 67 info.AddValue("BirthDate", BirthDate); 68 } 69 70 #endregion 71 }

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 lunedì 19 novembre 2007 18:35 | Filed Under [ Exam 70-536 Application Development Foundation ]

Feedback

Gravatar

# re: [70-536] - Interfaccia IDisposable e Pattern Dispose

Leggi anche questo post scritto dal team della BCL di .NET
http://blogs.msdn.com/bclteam/archive/2007/10/30/dispose-pattern-and-object-lifetime-brian-grunkemeyer.aspx
19/11/2007 19:32 | Matteo Baglini
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET