Mit dem XmlSerializer können nur öffentliche Typen serialisiert werden. Dieser Beitrag zeigt, wie das auch anders geht.

Eigentlich ist es ja ein alter Hut (und XML ist für viele out), aber aus Gewohnheit bin ich heute selbst wieder in diese Falle getappt. Es geht um eine kleine Library, die eine möglichst kleine Schnittstelle nach außen bieten soll. Diese dient dazu, um einige Konfigurationen vornehmen zu können. Diese werden im Hintergrund in XML-Dateien persistiert. Soweit kein Ding.

Nun liegt es in meiner Natur, dass in meinen Libraries nur die Klassen/Typen öffentlich zugänglich sind, die auch tatsächlich von anderen verwendet werden dürfen. Alle Typen, die mir intern helfen, alles geregelt zu bekommen, bleiben dabei nur innerhalb der Assembly sichtbar.

Damit möchte ich einigen Problemen vorbeugen:

  • Fehlverwendung der Library durch einen falschen Einstiegspunkt oder mit inkorrektem Setup
  • Fehlverhalten der Library (eben durch erstere Nutzung)
  • Streuung der Interna und damit verbundene Schwierigkeiten bei Updates (Änderungen der Sichtbarkeit, der Funktionalität, usw.)
  • Vereinfachte Verwendung der Library – je weniger öffentlich angeboten wird, desto leichter findet man sich zurecht

Soweit aber alles noch kein Thema.

Aus Gewohnheit habe ich dann zum XmlSerializer gegriffen. Alles was darüber serialisiert werden soll, muss allerdings öffentlich sein (es wird im Hintergrund Code generiert). Das wiederspricht meinem Vorhaben.

Zum Glück gibt es den DataContractSerializer als Alternative. Mittels DataContract kann eine Klasse als „Vertrag“ markiert werden, zu serialisierende Member/Properties sind mit Attribut DataMember zu versehen. Siehe als Beispiel:

[DataContract]
internal class Setting
{
    [DataMember]
    public string SubSetting1 { get; set; }
    [DataMember]
    public string SubSetting2 { get; set; }
}

So kann man das dann in ein XML serialisieren:

var serializer = new DataContractSerializer(typeof(Setting));
using (var stream = new XmlTextWriter(path, Encoding.Unicode))
{
    serializer.WriteObject(stream, objectToSerialize);
}

Und so wird das XML deserialisiert:

var serializer = new DataContractSerializer(typeof(Setting));
using (var stream = new XmlTextReader(path))
{
    Setting config = serializer.ReadObject(stream) as Setting;
    return config;
}

Viel mehr Hexerei ist das nicht und schon bleibt nur das Notwendige in unserer Library öffentlich sichtbar und deren Verwendung vereinfacht sich ungemein.

Happy Coding!

Über den Autor

Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler und Fotograf. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.

Hinterlasse einen Kommentar