Mein XmlSerializer Pattern

Die Idee hinter der .NET System.Xml.Serialization.XmlSerializer Klasse
ist, dass man einfach eine XML-Datei in einen Klassenbaum und andersrum serialisieren kann.

Wenn man XML-Schema-Dateien benutzt, kann das xsd.exe Tool diesen Klassenbaum für einen erstellen.

Aber für einfache Anwendungen braucht man nicht mal ein Schema. Man erstellt einfach eine Klasse, welche öffentliche Properties von einfachen Typen hat oder komplexe Typen, die wiederum einfache Typen enthalten.

Dann kann man dieses Objekt dem XmlSerializer vorwerfen und ist fertig. 🙂

Hier ist mein persönliches XmlSerializer-Programmiermuster für eine einfache Liste von Einstellungen:

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

[Serializable()]
[XmlRoot()]
public class Settings
{
   private static XmlSerializer s_Serializer;

   [XmlArray("SettingsList")]
   [XmlArrayItem("Setting")]
   public Setting[] SettingsList;

   static Settings()
   {
      //This way is safer than the more obvious
      //s_Serializer = new XmlSerializer(typeof(Settings));
      XmlReflectionImporter importer 
         = new XmlReflectionImporter();
      XmlTypeMapping xmlMapping = importer
         .ImportTypeMapping(typeof(Settings), null, null);
      XmlSerializerFactory factory 
         = new XmlSerializerFactory();
      s_Serializer = factory.CreateSerializer(xmlMapping);
   }

   public static Settings Deserialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Open, FileAccess.Read, FileShare.Read))
      {
         return (s_Serializer.Deserialize(stream) as Settings);
      }
   }

   public void Serialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Create, FileAccess.Write, FileShare.Read))
      {
         using (XmlTextWriter writer = new XmlTextWriter(stream
            , Encoding.UTF8))
         {
            writer.Formatting = Formatting.Indented;
            s_Serializer.Serialize(writer, this);
         }
      }
   }
}

[Serializable()]
public class Setting
{
   public String Key;

   public String Value;
}

Oder vielleicht braucht man auch nur einen einfachen Weg, einen Crash-Report zu haben, wenn die Applikation aus bisher unbekannten Gründen abstürzt:

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

[Serializable()]
[XmlRoot()]
public class ExceptionXml
{
   private static XmlSerializer s_Serializer;

   public String Type;

   public String Message;

   public String StackTrace;

   public ExceptionXml InnerException;

   static ExceptionXml()
   {
      //This way is safer than the more obvious
      //s_Serializer 
      //   = new XmlSerializer(typeof(ExceptionXml));
      XmlReflectionImporter importer 
         = new XmlReflectionImporter();
      XmlTypeMapping xmlMapping = importer
         .ImportTypeMapping(typeof(ExceptionXml), null, null);
      XmlSerializerFactory factory 
         = new XmlSerializerFactory();
      s_Serializer = factory.CreateSerializer(xmlMapping);
   }

   public static ExceptionXml Deserialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Open, FileAccess.Read, FileShare.Read))
      {
         return (s_Serializer.Deserialize(stream) 
            as ExceptionXml);
      }
   }

   public void Serialize(String filename)
   {
      using (FileStream stream = new FileStream(filename
         , FileMode.Create, FileAccess.Write, FileShare.Read))
      {
         using (XmlTextWriter writer = new XmlTextWriter(stream
            , Encoding.UTF8))
         {
            writer.Formatting = Formatting.Indented;
            s_Serializer.Serialize(writer, this);
         }
      }
   }

   public ExceptionXml()
   {
   }

   public ExceptionXml(Exception ex)
   {
      if (ex != null)
      {
         this.Type = ex.GetType().FullName;
         this.Message = ex.Message;
         this.StackTrace = ex.StackTrace;
         if (ex.InnerException != null)
         {
            this.InnerException 
               = new ExceptionXml(ex.InnerException);
         }
      }
   }
}