Wer in seinen Programmen auch mit DTOs (Data Transfer Objects) arbeitet, der steht vor dem Problem sich um deren Persistenz kümmern zu müssen. Der Namensraum System.Xml.Serialization bietet hierfür alles nötige. Und da wir gemäß dem DRY-Prinzip (Don’t Repeat Yourself) nicht für jedes DTO eine entsprechende Persistenzverwaltung schreiben möchten, machen wir das generisch:
VB.NET Code:
Imports System.Xml
Imports System.IO
Public Class ObjectPersistenceStore(Of T)
“‘ <summary>
“‘ Stellt den Zustand des Objekts anhand der übergebenen XML Daten wiederher
“‘ </summary>
“‘ <param name=“state“>Der Zustand des Objekts in Form eines XML Strings</param>
“‘ <returns>Eine Instanz des DTOs</returns>
“‘ <remarks></remarks>
Public Function LoadObjectState(ByVal state As String) As T
Dim result As T = Nothing
Try
Dim reader As New Serialization.XmlSerializer(GetType(T))
result = CType(reader.Deserialize(New StringReader(state)), T)
Catch ex As InvalidOperationException
Console.WriteLine(„Die XML Daten in der Datei sind fehlerhaft: “ + ex.Message)
Throw
Catch ex As FileNotFoundException
Console.WriteLine(„Datei nicht gefunden: “ + ex.Message)
Throw
Catch ex As NotSupportedException
Console.WriteLine(„Objekt „)
Throw
Catch ex As Exception
Console.WriteLine(ex.Message)
Throw ex
End Try
Return result
End Function
“‘ <summary>
“‘ Liefert den Zustand eines DTO zurück
“‘ </summary>
“‘ <param name=“dataTransferObject“>Das zu serialisierende Objekt</param>
“‘ <returns>Ein XML String</returns>
“‘ <remarks></remarks>
Public Function GetObjectState(ByVal dataTransferObject As T) As String
Dim result = String.Empty
Try
Dim xmlSerializer = New Serialization.XmlSerializer(GetType(T))
Dim stringWriter = New System.IO.StringWriter
xmlSerializer.Serialize(stringWriter, dataTransferObject)
result = stringWriter.ToString
Catch ex As InvalidOperationException
‚das Objekt muss einen leeren Konstruktor haben
Console.WriteLine(„Das Objekt kann nicht serialisiert werden: “ + ex.Message)
Throw
Catch ex As NotSupportedException
‚Interfaces können nicht serialisiert werden
Console.WriteLine(„Es wurde kein gültiges Objekt zum Serialisieren übergeben: “ + ex.Message)
Throw
Catch ex As Exception
Console.WriteLine(ex.Message)
Throw
End Try
Return result
End Function
End Class
C# Code:
using System;
using System.IO;
public class ObjectPersistenceStore<T>
{
/// <summary>
/// Stellt den Zustand des Objekts anhand der übergebenen XML Daten wiederher
/// </summary>
/// <param name=“state“>Der Zustand des Objekts in Form eines XML Strings</param>
/// <returns>Eine Instanz des DTOs</returns>
/// <remarks></remarks>
public T LoadObjectState(string state)
{
T result = default(T);
try
{
var reader = new System.Xml.Serialization.XmlSerializer(typeof(T));
result = (T)reader.Deserialize(new StringReader(state));
}
catch (InvalidOperationException ex)
{
Console.WriteLine(„Die XML Daten in der Datei sind fehlerhaft: “ + ex.Message);
throw;
}
catch (FileNotFoundException ex)
{
Console.WriteLine(„Datei nicht gefunden: “ + ex.Message);
throw;
}
catch (NotSupportedException ex)
{
Console.WriteLine(„Objekt „);
throw;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
return result;
}
/// <summary>
/// Liefert den Zustand eines DTO zurück
/// </summary>
/// <param name=“dataTransferObject“>Das zu serialisierende Objekt</param>
/// <returns>Ein XML String</returns>
/// <remarks></remarks>
public string GetObjectState(T dataTransferObject)
{
var result = string.Empty;
try
{
var xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
var stringWriter = new System.IO.StringWriter();
xmlSerializer.Serialize(stringWriter, dataTransferObject);
result = stringWriter.ToString();
}
catch (InvalidOperationException ex)
{
//das Objekt muss einen leeren Konstruktor haben
Console.WriteLine(„Das Objekt kann nicht serialisiert werden: “ + ex.Message);
throw;
}
catch (NotSupportedException ex)
{
//Interfaces können nicht serialisiert werden
Console.WriteLine(„Es wurde kein gültiges Objekt zum Serialisieren übergeben: “ + ex.Message);
throw;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
return result;
}
}
Bei der Verwendung ist zu beachten, dass Objekte, die deserialisiert werden sollen, einen leeren Konstruktur benötigen. Interfaces lassen sich per se nicht serialisiert.
Wenn man die oben geschilderte Logik z.B. in einem Interfaces deklariert und mit Dependency Injection bei dem Serializer arbeitet, dann kann man für beliebige DTOs verschiedene Persistenz-Manager implementieren (z.B. einen für Daten aus Dateien, einen anderen für Daten aus Datenbanken), die noch dazu unterschiedliche Serialisierungsformate verwenden. Und wenn man das ganze noch einen Schritt weiter treibt, kann man die Logik auch in einer ExtensionMethod kapseln und jedes DTO um diese erweitern.
Die Einsatzmöglichkeiten sind vielfältig, z.B. könnte man die Implementierung für eine Sitzungsverwaltung im eigenen ERP System verwenden. Ich verwende das Konzept für das Konfigurationsmanagement.
Gefällt mir:
Gefällt mir Wird geladen …