Work in Progress
Diese Seite ist aktuell im Review! Die Seite wurde noch nicht qualitätsgesichert und kann Fehler enthalten.
Die verlinkten Seiten sind ggf. nur für Schleupen-Mitarbeiter sichtbar.

Datenvertrag

Dieses Dokument beschreibt das Muster Datenvertrag in Hinblick auf WCF und WebService basierte Schnittstellen. Nach diesem Muster können Typen entwickelt werden, die zum Datenaustausch zwischen lose gekoppelten Einheiten (insbesondere unterschiedlichen Produkten) genutzt werden. Insbesondere zum Datenaustausch mit der Applikationslogik können nach diesem Muster aufgebaute Datenverträge genutzt werden. Das Muster wird als Klasse implementiert.

Design

In Schnittstellen, die Daten zwischen lose gekoppelten Einheiten (z.B. Workflow-Instanzen und Applikationslogik) austauschen, sollen nur Standard-Datentypen (s. Datentypen und Datentyp-Mapping) verwendet werden. Der Datenvertrag ist Bestandteil der Schnittstelle und wird daher der Interface-Assembly hinzugefügt. Als Namensraum ist Contracts zu verwenden  (1.0: Deklaration von Namensräumen (Namespace)). Als Postfix der Klasse ist zur Unterscheidung vom Domänenmodell das Postfix Contract zu verwenden.

Aus Schnittstellensicht kann man sich einen Datenvertrag als XML-Dokument vorstellen.

Die Datenverträge haben nichts mit Domänen-Modellen zu tun! Ein Datenvertrag stellt die serviceorientierte Umsetzung eins DTOs (s. http://martinfowler.com/eaaCatalog/dataTransferObject.html) dar.

Die Nutzung eines Datenvertrags ist auf die Schnittstellen der definierenden Applikation beschränkt. Dies bedeutet, dass eine Serverschnittstelle keine Datenverträge einer anderen CS Applikation entgegen nehmen darf. Auch dürfen in Datenverträgen keine Referenzen auf Datenverträge bzw. Enumerationen anderer Applikationen vorkommen.

Sollen die Datenverträge zur späteren Verwendung in der Datenbank abgelegt werden, wird die XML-Serialisierung und -Deserialisierung über die Klasse XmlStringSerializer genutzt (vgl. Muster - Serialisierung von Datenverträgen (DataContractStringSerializer), 1.0). Zur Kommunikation mit durch Kunden anpassbaren Komponenten (z.B. Workflow) kann ein XML-Schema über die XML Datentypen veröffentlicht werden.

Implementierung

Ein Datenvertrag wird in Form einer Klasse implementiert. Die Klasse wird mit dem Attribut DataContract versehen.

Das Attribut DataContract wird durch das .NET Framework zur Verfügung gestellt. Die Assembly System.Runtime.Serialization muss eingebunden sein.

using System.Runtime.Serialization;

[Pattern(Schleupen.CS.SY.Patterns.DataContract.Container41)]
[DataContract(Namespace = ALXmlProvider.TasksNamespaceUri, IsReference = true)]
[Serializable]
public sealed class TaskContract
{
    // ...
}

Der Namespace sollte über eine separate Klasse zurückgegeben werden. Diese kann analog zur Klasse Schleupen.CS.SY.WF.ALXmlProvider aufgebaut werden (vgl. Muster - Deklaration von Namensräumen (Namespace), 1.0):

public static class ALXmlProvider
{
    public const string NamespaceUri = "urn:CS.SY";
    public const string TasksNamespaceUri = NamespaceUri + "/Tasks";
    // ...
}

Die Eigenschaft IsReference sollte stets true sein. Dies führt dazu, dass die Objekte in der serialisierten Darstellung mit einer eine ID-Eigenschaft versehen werden. Wird ein serialisierte Objekt in einem anderen Kontext erneut verwendet wird auf diese ID verwiesen, statt den Serialisierungsprozess erneut durchzuführen. Diese Eigenschaft verringert die Nachrichtengröße, erzeugt auf der Deserialisierungsseite den gleichen Objektgraphen (Referenzgleichheit) und unterstützt zyklische Referenzen die ansonsten zu einer Serialisierungsausnahme führen.

Elemente und Eigenschaften

Jede zum Datenaustausch relevante Eigenschaft muss mit dem Attribut DataMember versehen werden. Nicht explizit mit DataMember angegebene Eigenschaften werden beim Serialisieren ignoriert.

[DataMember]
public string TypeShortcut { get; set; }

Um das Datenvolumen des Contracts gering zu halten sollten Werte nur serialisiert werden, wenn sie ungleich dem Standardwert sind. Dazu muss beim DataMember-Attribut EmitDefaultValue auf false gesetzt werden.

 [DataMember(EmitDefaultValue=false)]
 public int? Id{ get; set; }

 [DataMember(EmitDefaultValue=false)]
 public int Count{ get; set; }

Die Zuweisung eines Standardwertes ist durch folgenden Code zu realisieren. Optional kann die Eigenschaften des Datenvertrages mit dem Attribut DefaultValue versehen werden um die Unterstützung mit dem Designer zu gewährleisten.

Cookie Consent mit Real Cookie Banner