XmlSerializer permette con poche e semplici righe di codice di serializzare/deserializzare campi e proprietà pubbliche di un oggetto in/da un formato XML.
Ci possiamo imbattere però in errori inaspettati, ad esempio serializzando collezioni i cui elementi sono determinati a runtime o in presenza di vincoli di ereditarietà tra le classi molto complessi.
Un'alternativa più flessibile in questi casi è personalizzare completamente il processo di serializzazione/deserializzazione, implementando l'interfaccia IXmlSerializable.
Basta creare la collection implementando l'interfaccia IXmlSerializable:
public class RuntimeCollection : Collection<BaseClass> , IXmlSerializable { public System.Xml.Schema.XmlSchema GetSchema() { return null; } public void ReadXml(System.Xml.XmlReader reader) { //mi sposto sul primo elemento della collezione reader.Read(); //finchè non raggiungo il nodo finale della collezione while (reader.NodeType != System.Xml.XmlNodeType.EndElement) { //recupero l'attributo che contiene le informazioni sul tipo string type = reader.GetAttribute(0); //istanzio una nuova istanza di XmlSerializer XmlSerializer serializer = new XmlSerializer(Type.GetType(type)); //deserializzo BaseClass item = (BaseClass)serializer.Deserialize(reader); //aggiungo l'istanza alla collezione this.Add(item); } } public void WriteXml(System.Xml.XmlWriter writer) { //per ogni elemento della collezione foreach (BaseClass p in this) { //inizializzo una nuova istanze di XmlSerializer XmlSerializer serializer = new XmlSerializer(p.GetType()); //inserisco le informazioni sul tipo XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); namespaces.Add("type", p.GetType().AssemblyQualifiedName); //serializzo passondo il writer da riempire serializer.Serialize(writer, p, namespaces); } } }
Il metodo WriteXml scorre la collezione e crea per ogni elemento un'istanza di XmlSerilizer con il tipo dell'oggetto corrente. In previsione del processo di deserializzazione, scriviamo queste informazioni nel file XML in modo da recuperarle quando in concomitanza con quest'ultima viene richiamato il metodo ReadXml, che dal canto suo recupera le informazioni sul tipo e inizializza una nuova istanza di XmlSerializer per ricreare gli elementi che componevano la collezione.
L'interfaccia IXmlSerializable è presente anche nelle versioni 1.x del .NET Framework, non è documentata ed è implementata solamente dalla classe DataSet.
Con la versione 2.0 viene alla luce e riceve il giusto risalto, visto l'estrema importanza di personalizzare il processo di serializzazione/deserializzazione con la classe XmlSerializer.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.