Data Transfer Objects verwalten

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.

2 thoughts on “Data Transfer Objects verwalten

  1. […] Data Transfer Objects verwalten […]

    Gefällt mir

  2. […] Informationen in irgendeiner Form weiter übergeben müssen. Eine Möglichkeit wäre gewesen ein DTO zu definieren und dieses immer im Konstruktor in die nächste Klasse weiter zu […]

    Gefällt mir

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: