Post on 01-Aug-2020
transcript
Datasets als DTO im Web Service-Umfeld
Markus LegnerSenior Consultant
Tricept Informationssysteme AGBenzstr. 3770736 Fellbach0711 / 52 08 92 60www.tricept.de
Ein Erfahrungsbericht
Datasets als DTO im Web Service-Umfeld 1
1 Einleitung
Wie können relational strukturierte Daten möglichst effizient und generisch über eine Web Ser-
vice-Schnittstelle transportiert werden, wenn Client und Server in heterogenen Programmierspra-
chen entwickelt sind?
Mit dieser Frage mussten wir uns beschäftigen, als zu Beginn der Entwicklung von SIMplus die
neu zu entwickelnde Web Service-Schnittstelle (WS) konzipiert wurde. Ein Teilbereich dabei ist
der Transport komplexer Nutzdaten über diese Schnittstelle.
Folgende konkrete Anforderungen hatten dabei besondere Priorität:
- Effizientes Erstellen der benötigten Datenstrukturen für den Transport
- Effizientes Erstellen des Mapping zwischen Datenstruktur und Business-Entities
- Einfache Verwendung und einfaches Binding der Daten im Client
- Zukunftssicherheit der Lösung
- Datenstruktur soll zum generischen Charakter der eingesetzten WS-Schnittstelle passen
Nach Analyse und Abwägung der möglichen Optionen – auf die in diesem Artikel nicht näher
eingegangen wird – haben wir uns dafür entschieden, an den Stellen, an denen komplexe relati-
onale Daten transportiert werden, auf (als XML serialisierte) ADO.NET Datasets zu setzen.
Im Folgenden stelle ich unseren Ansatz für die Verwendung von Datasets als Data Transport Ob-
jects1 (DTO) im Kontext von Web Services vor. Als Besonderheit basieren dabei Client und Ser-
ver auf zwei heterogenen Programmiersprachen - .NET und Smalltalk.
1 http://de.wikipedia.org/wiki/Transferobjekt
Datasets als DTO im Web Service-Umfeld 2
2 Anwendung und Systemarchitektur
SIMplus Mit SIMplus wurde – in Zusammenarbeit mit dem Kunden – eine neue WPF-Applikation entwi-
ckelt, die komplexe Pflegemasken und -prozesse im Bereich Sicherheitenmanagement (SIM) in
einer neuen, innovativen Oberfläche bündelt.
Abbildung 1: Screenshot SIMplus
Das Besondere an SIMplus sind die grafisch aufbereiteten Benutzeroberflächen. Transparente
Darstellungen verschaffen dem Anwender einen guten Überblick bei der komplexen Datenpflege
im Bereich Sicherheitenmanagement. Durch Einsatz der WPF-Technologie wurde es ermöglicht,
Darstellungen von Vermögenswerten, Forderungen und Sicherungsvereinbarungen klar und ver-
ständlich in Oberflächen zu visualisieren. Ein schnelles Zurechtfinden und eine einfache Orientie-
rung optimieren den Arbeitsprozess, reduzieren die Bearbeitungszeit und steigern die Qualität
der Daten.
3-Schichten-Architektur Das gesamte System basiert – wie in Abbildung 2 dargestellt – auf einer 3-Schichten-Architektur.
SIMplus kommuniziert dabei via Web Services mit dem sogenannten Prozessserver (PS), der die
Business-Logik kapselt und in Form von Web Services bereitstellt. Der PS kommuniziert auf der
anderen Seite mit den Backend-Systemen – z.B. Mainframe oder auch direkt mit einer DB2-
Datenbank – von denen Daten zur Verfügung gestellt werden.
Datasets als DTO im Web Service-Umfeld 3
Client (SIMplus)
[.NET]
Datenbanken
Prozesserver (PS)
[Smalltalk]
Mainframe
Web Service
Abbildung 2: 3-Schicht-Systemarchitektur
Da dieser Artikel primär den Datentransport zwischen SIMplus und PS behandelt, werden im
Folgenden noch einige relevante technischen Informationen zu diesen beiden System-
Komponenten geliefert.
SIMplus Die Applikation basiert auf dem .NET-Framework 3.5 und der Windows Presentation Foundation
(WPF).
Architektonisch setzt sie auf unserem komponentenbasierten Client-Framework TARIS2 auf. Das
bedeutet, die Oberfläche gliedert sich in eigenständigen Komponenten, die effizient wiederver-
wendet werden können. Eine Komponente weiß dabei wie sie sich selbst darstellt – definiert also
die eigene Oberfläche – und welche(n) Data Service(s) verwendet werden um Daten zu lesen
und zu schreiben.
Zudem veröffentlicht die Komponente über ein klar definiertes Interface – den sogenannten Cont-
ract – Funktionen und Eigenschaften, die von extern genutzt werden können. Der Contract wird
darüber hinaus auch verwendet um über eine Factory3 eine konkrete Instanz einer Komponente
zu erzeugen.
Wie erwähnt wird der komplette Datenzugriff einer Komponente über eine oder mehrere Data
Services (DS) abgewickelt. Ein DS implementiert Funktionen für den Zugriff auf Daten und veröf-
fentlicht diese Funktionen über ein Interface. Im Fall von SIMplus greifen die DS dann über Web
Services auf die Business-Funktionen des Prozessservers zu (s. Kapitel 3).
2 Tricept Advanced Rolebased Integrated SmartClient 3 http://de.wikipedia.org/wiki/Fabrikmethode
Datasets als DTO im Web Service-Umfeld 4
Abbildung 3: Ausschnitt des UML-Klassendiagramm für das TARIS- Komponentenmodell
Prozessserver Der Prozessserver (PS) ist eine in Smalltalk implementierte Middleware-Lösung, auf der die für
SIMplus benötigte Business-Logik implementiert ist. Historisch betrachtet ist er durch das
„heraustrennen“ der Business-Logik-Schicht aus einer vorhandenen Smalltalk-Applikation (Fat
Client) entstanden.
Ziel dabei war es, die vorhandene Logik auch anderen Anwendungen verfügbar zu machen. Da-
her werden die implementierten Business-Funktionen den Clients plattformunabhängig in Form
von Web Services zur Verfügung gestellt.
Abbildung 4: Generierte Methode „processFrontendRequest“ im Client
Die Web Service-Schnittstelle ist generisch konzipiert. Das bedeutet, durch die Implementierung
zusätzlicher fachlicher Funktionen ändert sich die Web Service-Definition (WSDL-Beschreibung)
nicht. Die zentrale Web Service-Methode um dem PS einen Request zu übergeben, ist dabei
immer die in Abbildung 4 abgebildete Methode „processFrontendRequest“ (abgebildet ist ein
Ausschnitt des von Visual Studio 8 aus der WSDL generierten Client-Codes).
Datasets als DTO im Web Service-Umfeld 5
Diese erwartet als Eingabe u.a.
• den RequestName – das ist der konkrete Name der aufzurufenden Business-Funktion
• ein Objekt vom Typ FrontendRequest – dieses kapselt in flexibler Form (Dictiona-ry/Map) alle Eingabe-Parameter für die aufzurufende Business-Funktion4.
3 Verarbeitung von Daten im Client
In diesem Kapitel wird exemplarisch auf die konkrete Verwendung von Datasets im Fall von
SIMplus eingegangen. Dazu gehören die Generierung neuer Datasets, deren De-/Serialisierung,
sowie die Einbindung eines Datasets in einen Data-Service.
Zuvor wird noch kurz auf das Konzept des Data-Service eingegangen, sowie ein Überblick über
die Verwendung von typisierten und untypisierten Datasets gegeben.
Data-Services und Datasets
Grundkonzept Data-Service Ein Data-Service ist im TARIS-Framework ein Objekt der Datenschicht im Client. Er schafft eine
Abstraktion von der konkreten Schnittstelle über die Daten gelesen und geschrieben werden.
Jeder Data-Service implementiert dabei eine Schnittstelle über die bestimmte Methoden veröf-
fentlicht werden. Wie die fachlichen Komponenten, werden auch Instanzen eines Data-Service
über ihr Interface durch eine spezielle Factory erzeugt. Dadurch wird es z.B. einfach möglich den
Datenzugriff zwischen remote und lokal zu switchen (ggf. erforderlich für Tests) – ohne dass der
Client-Code angepasst werden muss.
Data-Services in SIMplus… Bei SIMplus erlaubt es die Struktur der neu geschaffenen Web Service-Schnittstelle, dass etwa
90% der benötigten Funktionalität für den Datenzugriff in einem abstrakten Data-Service
ProfisOnlineDS implementiert ist. Die konkreten Data-Service-Klassen, die in den Komponen-
ten instantiiert werden, parametrisieren diesen lediglich (Name der Business-Klasse auf dem PS)
oder erweitern ihn ggf. um fehlende Funktionen (Beispiel s. Abbildung 12).
…und die Verwendung von Datasets Wie in Kapitel 2 beschrieben werden die Eingabe- und Ausgabeparameter der zentralen WS-
Methode „processFrontendRequest“ in Form von Container-Objekten übergeben, bzw. zurückge-
liefert. Neben primitiven Typen können darin auch komplexe Parameter vom Typ DataSet ent-
halten sein – diese werden jedoch als XML serialisiert in Form eines String-Parameters überge-
ben, bzw. zurückgeliefert.
4 Auch für die Rückgabe der Business-Funktion gibt es eine entsprechende Container-Klasse FrontendRe-sult, von der immer eine Instanz im zurückgelieferten SoapResult enthalten ist.
Datasets als DTO im Web Service-Umfeld 6
In Abbildung 5 ist exemplarisch die Serialisierung eines Dataset-Parameters und das Hinzufügen
zu dem Dictionary abgebildet, das im weiteren Verlauf noch in einen FrontendRequest verpackt
wird. Parallel dazu zeigt Abbildung 6 die Deserialisierung eines Datasets aus der Rückgabe einer
Business-Funktion.
Typisierte Datasets Grundsätzlich werden in der Web Service-Schnittstelle von SIMplus nur typisierte Datasets ver-
wendet. Da auf dem Server sowieso explizit definiert werden muss, welche Daten benötigt wer-
den, und auf welche Tabellen/Attribute im Dataset ein Wert abgebildet wird, bekommt man die In-
formation über die Struktur des Datasets sozusagen umsonst. Diese Informationen werden dann
zusätzlich verwendet um daraus die XSD-Beschreibung des typisierten Datasets zu generieren.
Das hat den Vorteil, dass der Zugriff auf die Daten einfacher und mit besser lesbarem Code im-
plementiert werden kann. Ein weiterer Vorteil ist, dass es ein klar definiertes Schema für jedes
Dataset gibt, das für die Serialisierung und Deserialisierung verwendet wird. Abbildung 7 zeigt
einen Auszug aus einem XML-serialisierten typisierten DataSet
public virtual void Update( DataSet dataSet) { P3.ProzessServerWs.OnlineSession. Dictionary requestDict = new P3.ProzessServerWs.OnlineSession. Dictionary (1); StringWriter writer = new StringWriter (); dataSet.WriteXml(writer, XmlWriteMode .IgnoreSchema); requestDict.AddIndexKeyValue(0, "dataSet" , writer.ToString()); this .Session.ProcessFrontendRequestWithExceptions( this .BusinessClassName + ".updateDataSet" , requestDict);
}
public virtual void GetOverview( DataSet dataSet) { dataSet.Clear(); String response = this .Session.ProcessFrontendRequestWithExceptions( this .ProfisClassName() + ".getUebersicht" ) as string ; System.IO. TextReader reader = new StringReader (response); dataSet.ReadXml(reader, XmlReadMode.IgnoreSchema); dataSet.AcceptChanges(); }
Abbildung 5: Serialisierung eines Eingabeparameters vom Typ DataSet
Abbildung 6: Deserialisierung eines Ausgabeparameters vom Typ DataSet
Datasets als DTO im Web Service-Umfeld 7
<PersonAllgemeinDataSet>
<Person>
<P_NR>1230000</P_NR> <MANDANT_NR>1</MANDANT_NR> <kontoKurzBez>Test,Heinz*,</kontoKurzBez> <zielGruppeNr>5200</zielGruppeNr> <name>Test</name>
<vorname>Heinz</vorname>
<strasse>Teststr.</strasse>
<hausNr>32</hausNr> <plz>99999</plz> <ort>Stuttgart</ort>
…
</Person> </PersonAllgemeinDataSet>
Abbildung 7: Auszug aus einem in XML serialisierten PersonAllgemein-DataSet
Datasets als DTO im Web Service-Umfeld 8
Vorgehen: Erstellung einer neuen Business-Funktion mit zugehörigem Data-Service
Schritt 1: Erstellen einer neuen Business-Funktion (Server) Dabei wird auf dem Prozessserver eine neue Business-Funktion implementiert, die über den ge-
nerischen Web Service aufgerufen werden kann. Dazu wird in Smalltalk eine neue Methode an-
gelegt (in einer neuen oder bestehenden Klasse), die die benötigte Funktionalität implementiert.
Der komplette Name der Business-Funktion (s. Parameter RequestName in Abbildung 4) für den
Aufruf der Funktion über den Web Service ergibt sich dann aus Klassenname + Methodenname.
Ein solcher Name kann beispielsweise PbtPersonAllgemein.getOverview lauten.
Da dieser Schritt komplett in der Smalltalk-Umgebung stattfindet, wird an dieser Stelle nicht nä-
her darauf eingegangen.
Schritt 2: Erstellen eines neuen Datasets (Server) In diesem Schritt wird das Dataset angelegt, dass als DTO für diese Business-Funktion verwen-
det wird.
Für die Erzeugung und Konfiguration eines Dataset für eine neue Business-Funktion, existiert ein
auf Smalltalk basierendes – von Tricept entwickeltes – Tool. Dieser Generator ermöglicht es auf
einfache Art und Weise Teile des Entitäten-Modells aus dem Business-Layer in ein typisiertes
Dataset zu überführen.
Abbildung 8: Schritt 1 - Definition der benötigten Entitäten/Tabellen
Dabei kann definiert werden, welche Entitäten und Attribute, sowie welche Relationen zwischen
Entitäten benötigt werden. Als Ergebnis erhält man ein typisiertes Dataset, das den benötigten
Ausschnitt aus dem Datenmodell abbildet.
Dieser Schritt ist nur erforderlich, wenn nicht bereits ein geeignetes existiert. Natürlich können
auch mehrere Business-Funktionen denselben Dataset-Typ verwenden.
Datasets als DTO im Web Service-Umfeld 9
Abbildung 9: Schritt 2 - Definition der benötigten Attribute
Die vom Generator erzeugte XSD-Beschreibung ist in Abbildung 10 abgebildet.
Abbildung 10: XSD-Code für das PersonAllgemein-Dataset
Datasets als DTO im Web Service-Umfeld 10
Schritt 3: Einbinden des neuen Dataset in Visual Studio (Client) Die unter Smalltalk generierte XSD-Datei kann jetzt direkt dem Visual Studio-Projekt (VS) hinzu-
gefügt werden.
Nach dem Setzen der beiden Eigenschaften „Custom Tool Namespace“ und „Custom Tool“ ge-
neriert Visual Studio automatisch alle weiteren von VS benötigten Dateien (z.B. die .designer.cs-
Datei für den Dataset-Designer).
Abbildung 11: Erforderliche Einstellungen in Visual Studio
Schritt 4: Erstellen des Data-Service (Client) Für das Erstellen des neuen Data-Service im Client existiert ein Visual Studio-Template, das die
benötigte Klassen und Interfaces generiert. Abbildung 12 zeigt auszugsweise den für die Data-
Service-Klasse PersonAllgemeinOnlineDS generierten Code. Wie weiter oben erwähnt erbt
die Data-Service-Klasse viele Methoden von ProfisOnlineDS. Sie parametrisiert allerdings
den Klassennamen des Business-Objektes auf dem Server und implementiert die zusätzlich be-
nötigten Funktionen GetPerson() und GetAccountManagerForPerson() .
public class PersonAllgemeinOnlineDS : ProfisOnlineDS , IPersonAllgemeinDS { public PersonAllgemeinOnlineDS( ProfisOnlineSession session) : base (session) { } public override String BusinessClassName() { return "PbtWSPersonAllgemein" ; } public void GetPerson ( DataSet dataSet, int identifier) {…} public void GetAccountManagerForPerson( DataSet dataSet, int identifier) {…} }
Abbildung 12: Generierter Code der Data-Service-Klasse für den Client
Datasets als DTO im Web Service-Umfeld 11
Schritt 5: Verwendung des neuen Data-Service (Client) Der Aufruf einer Business-Funktion auf dem Prozessserver erfolgt über eine Instanz des in
Schritt 4 erstellten Data-Service, die über eine Factory erzeugt wird (s. Abbildung 13).
Abbildung 13: Aufruf der Business-Funktion PbtPersonAllgemein.getOverview im Client
Vor dem Aufruf wird das benötigte Dataset erzeugt und dann an den Data-Service übergeben.
Nach dem Aufruf enthält das Dataset die vom Server zurückgelieferten Daten.
Schritt 6: Verwendung des Dataset innerhalb einer Komponente (Client) In der Praxis hat sich gezeigt, dass es sinnvoll und effizient ist, die fachlichen Komponenten
möglichst so zu konzipieren, dass die benötigten Daten durch einen einzigen Data-Service gele-
sen und geschrieben werden können5.
Lokale Speicherung der Daten
Dieser Ansatz spiegelt sich daher auch in den verwendeten Komponenten-Basisklassen wieder.
So hat jede Komponente neben der Instanz der Oberfläche und des Data-Service, auch ein Pro-
perty vom Typ DataSet , in dem die Daten ‚lokal‘ vorgehalten werden (s. Abbildung 3).
Binding an die Oberfläche
Nach dem Lesen wird das Dataset an die UI übergeben, die ihren DataContext so setzt, dass
die Controls mit WPF-Mechanismen einfach an die Daten gebunden werden können. Im Normal-
fall reicht es dazu aus den DataContext auf eine Tabelle6 oder auf die erste Reihe einer Tabelle7
zu setzen (s. Abbildung 14).
5 Das schließt nicht generell aus, dass eine Komponente insgesamt mehrere Data-Services nutzt oder dass ein bestehender Data-Service von mehreren Komponenten genutzt wird. 6 Im Fall einer Listen-Komponente 7 Hat man eine Maske zur Bearbeitung von Stammdaten zu einer Person kann es z.B. ein DataSet mit einer Tabelle „Person“ geben, das immer nur 1 Datensatz enthält – die gerade bearbeitete Person.
// Instantiierung des Data-Service IPersonAllgemeinDS service = DataServiceProvider .Singleton.GetDataService< IPersonAllgemeinDS >( this .Session); // Instantiierung des DataSet PersonAllgemeinDataSet dataSet = new PersonAllgemeinDataSet ();
try { mService.GetOverview(dataSet, entityId); }
catch { …}
Datasets als DTO im Web Service-Umfeld 12
In komplexeren Szenarien kann es aber auch sinnvoll sein, unterschiedliche Bereiche der Ober-
fläche an unterschiedliche Daten aus dem Dataset zu binden.
Speichern von Änderungen
Sollen die geänderten Daten einer Komponente gespeichert werden, werden zunächst die aktu-
ellen Daten aus der Oberfläche zurück ins lokale Dataset geschrieben.
Nach der gültigen Validierung wird die Update-Methode (s. Abbildung 5) des entsprechenden Da-
ta-Service aufgerufen und das aktualisierte lokale Dataset mit übergeben.
// Setzen des DataContext auf die komplette Tabelle „Person“ (Listen-Komponente)
this .DataContext = this .GetDataContextFromDataSet(dataSet, “Person”);
oder
// Setzen des DataContext auf die Reihe 1 aus Tabel le „Person“ (Anz./Bearbeitung)
this .DataContext = this .GetDataContextFromDataSet(dataSet, “Person[0]”);
Abbildung 14: Setzen des DataContext
Datasets als DTO im Web Service-Umfeld 13
4 Fazit
Wie gezeigt hatten wir im Projekt SIMplus die Möglichkeit, eine komplett neue generische Web
Service-Schnittstelle zu konzipieren und zu entwickeln. Da die Applikation sehr stark mit relatio-
nal-strukturierten Daten arbeitet – wie die meisten reinen Business-Applikationen – wurde nach
einem effizienten Weg gesucht derartige Daten über die Web Service-Schnittstelle zu transportie-
ren.
Gefunden haben wir diese Möglichkeit in der ADO.NET Dataset-Technologie. Die Verwendung
von Datasets hat den Vorteil, dass diese sehr gut in den .NET-Framework und WPF integriert
sind. Ein zweiter wichtiger Vorteil ist, dass sich Datasets von Haus aus problemlos in XML seria-
lisieren und deserialisieren lassen – im Client ist der Zusatzaufwand dafür kaum erwähnenswert.
Aus Sicht des Applikation-Servers handelt es sich um ein strukturiertes XML-Objekt mit klarem
Schema, das heutzutage in allen verfügbaren Sprachen einfach erstellt, verarbeitet und befüllt
werden kann.
Datasets als DTO im Web Service-Umfeld 14
Anhang A - Links
ADO.NET DataSet
http://msdn.microsoft.com/de-de/library/bb979079.aspx
DataSet und XML
http://msdn.microsoft.com/de-de/library/84sxtbxh(v=VS.80).a spx