Wie behandelt man Dtos für Objekte, die mehrere Schnittstellen implementieren?

8

Wir verwenden Dtos in unserer WCF-Service-Schnittstelle, haben aber Probleme, wenn das Business-Objekt, das die Dto repräsentiert, mehr als eine einzige Schnittstelle implementiert und wir die Dtos in diesen verschiedenen Kontexten zurückgeben wollen und auch können die Dtos polymorph auf dem Client zu behandeln.

Nehmen wir zum Beispiel an, wir haben eine Schnittstelle für ein IBusinessObject mit mehreren Eigenschaften, die Details der Beziehungen des Objekts, der Attribute des Objekts usw. enthalten. Ich habe mehrere Implementierungen von diesem, die LinearBusinessObject sind, die% implementieren. co_de% und IBusinessObject . Es gibt andere Implementierungen von ILinear , die keine Geschäftsobjekte sind, sondern nur einfache lineare Dinge.

Unser Dienst verfügt über eine Methode zum Abrufen eines Geschäftsobjekts. Dies gibt eine Basis-Dto-Klasse ( ILinear ) zurück, die die gemeinsamen Teile von BusinessObjectDto (Beziehungsattribute usw.) und IBusinessObject , die LinearBusinessObjectDto erweitern, deklariert und zusätzliche Informationen über die lineare Seite der Dinge hinzufügt. Dies ist in Ordnung und ermöglicht dem Client, die zurückgegebene BusinessObjectDto mit einem gewissen Grad an Polymorphie zu behandeln.

Wir wollen auch eine Methode, die eine lineare Sache bekommt. Dies gibt eine Basisklasse BusinessObjects zurück, die die gemeinsamen linearen Details enthält. Die einfache lineare Objektimplementierung erweitert LinearDto und alles ist gut. Aber jetzt habe ich ein Problem, da ich meine LinearDto nicht von LinearBusinessObjectDto und und LinearDto erweitern kann, da nur eine einzige Vererbung unterstützt wird und ich keine Schnittstellen verwenden kann, da WCF nicht weiß, welche Typen um dann die Servicevertragsdefinitionen in die WDSL einzufügen.

Also habe ich angefangen, 2 dtos für meine BusinessObjectDto zu haben, eine, die von LinearBusinessObject ( BusinessObjectDto ) abgeleitet ist und eine, die von LinearDto ( LinearBusinessObjectAsBusinessObjectDto ) abgeleitet ist und dann jede basierend auf der Schnittstelle I konvertiert interessiert mich.

Das scheint so zu sein, dass es zu vielen zusätzlichen Dto-Klassen (von denen ich bereits viele habe) führen wird, und ich frage mich, ob es eine bessere Lösung als diese gibt? Oder müssen wir damit leben?

    
Sam Holder 07.03.2012, 09:48
quelle

7 Antworten

13
Ein weiser Mann sagte mir einmal, dass Objektorientierung der Feind der Dienste sei.

Es scheint mir, dass dies eher ein allgemeines OO / SOA-Problem als ein spezifisches WCF-Problem ist: der alte Rat von "Favor Composition over Inheritance" kommt mir in den Sinn. Wenn es speziell um Dienstleistungen geht, sollten polymorphe Designs nicht das sein, was Sie in Ihrer DTO-Schicht suchen. Sie sollten vermeiden, DTOs zu verwenden, die Vererbung oder Interfaces verwenden (und Interfaces sind nicht einmal möglich, es sei denn, Sie serialisieren / deserialisieren dynamisch ... Sie können keine konkreten Proxies mit SVCUtil erzeugen, da die konkreten Typen zum Generierungszeitpunkt nicht bekannt sind Speicher ist dies möglich, wenn Sie ChannelFactories in Ihrem .NET-Client verwenden ... Ich kann mich jedoch nicht an die Details erinnern.)

Im Allgemeinen, wenn Sie DTO / DataContracts erstellen, definieren Sie nur Member / Eigenschaften in ihnen, die konkret sind. Ihr DTO-Modell sollte flach und plattformübergreifend sein, nicht objektorientiert.

    
MrLane 16.03.2012, 04:20
quelle
1

Ich glaube, ich habe verstanden, was Sie zu sagen versuchen, also bitte entschuldigen Sie, wenn ich Miss interpretiert habe. Grundsätzlich haben Sie die folgenden Objekte, die Sie über einen WCF-Vertrag übergeben möchten:

%Vor%

Sie haben erwähnt, dass Sie keine Schnittstellen im WCF-Vertrag verwenden möchten, da Sie möglicherweise verschiedene Implementierungen der Schnittstelle zurückgeben.

Meine Frage an Sie ist, brauchen Sie tatsächlich die gleiche Implementierung des Objekts, das an den Client zurückgegeben wird. Brauchen Sie tatsächlich, dass der Client eine Instanz von CombinationOfAAndB empfängt, oder kann es etwas anderes sein, das dieselbe Signatur hat? Zweitens gibt der Client jemals eines dieser Objekte zurück, und wenn ja, wie trifft die obige Frage zu?

Wenn die Antwort darauf ist, dass Client und Dienst nicht interessiert sind, können Sie ein clientseitiges spezifisches Objekt einführen, das die fraglichen Interfaces implementiert und in den Client-Wissenstypen registriert ist (KnownTypes sind für Deserialisierung, nicht Serialisierung) und lassen WCF Mach das Mapping.

%Vor%

Ja, dies führt ein anderes DTO-Objekt ein, aber es muss nur auf dem Client vorhanden sein und bedeutet, dass Ihr gesamter Vertrag auf einer Schnittstelle implementiert ist. Sie können die Implementierung / den Austausch in verschiedenen Objekten auf dem Client oder Server ohne Auswirkungen ändern auf der anderen Seite, solange der Vertrag nicht gebrochen ist. Sie können sogar neue Eigenschaften und Methoden einführen, ohne bestehende Clients zu zerstören, wenn dies korrekt und im Rahmen des Zumutbaren geschieht.

    
Bronumski 15.03.2012 22:35
quelle
0

WCF bietet einen Haken zum Definieren "bekannter Typen" für Schnittstellen und Vererbungsketten. Ich bin mir nicht sicher, ob ich entweder das Attribut ServiceKnownType oder KnownType-Attribut ist direkt anwendbar zu dem, was du beschreibst, aber es ist definitiv einen Blick wert.

    
Sixto Saez 07.03.2012 14:16
quelle
0

Ist dies ein interner Web-Service oder werden Sie ihn extern hosten?

Wenn dies intern ist, sehen Sie sich die "Reuse types in referenzierten Assemblies" -Option im "Dienstreferenz konfigurieren" -Dialog

an
  1. Verweisen Sie auf Ihre DTO-Assembly (stellen Sie sicher, dass sich Ihre DTOs in einer eigenen Assembly befinden) im Client-Projekt

  2. Rufen Sie das Dialogfeld "Dienstreferenz konfigurieren" für den gewünschten WCF-Dienst auf

  3. Aktivieren Sie das Kontrollkästchen "Typen in referenzierten Assemblys wiederverwenden"

  4. Wählen Sie das Optionsfeld "Typen in angegebenen referenzierten Assemblys wiederverwenden"

  5. Wählen Sie die DTO-Assembly aus der Liste aus.

Das Ergebnis, das Sie von Ihrem ServiceClient() erhalten, ist der tatsächliche Typ aus der referenzierten DTO-Assembly, kein generierter Proxy. Sie sollten jetzt in der Lage sein, Ihre Objekte polymorph zu bearbeiten.

    
Patrick 13.03.2012 19:32
quelle
0

Vielleicht könnten Sie stattdessen die Basisobjekte kapseln. Sie haben also Ihre BusinessObjectDto- und LinearDto-Objekte. Sie haben dann Ihr LinearBusinessObjectDto, das zwei Eigenschaften enthält, eine vom Typ BusinessObjectDto und eine andere vom Typ LinearObjectDto. Wenn die Service-Methode ein LinearBusinessObjectDto zurückgibt, initialisiert sie jede dieser Eigenschaften. Sie könnten dann die Schnittstellen auf dem LinearBusinessObjectDto implementieren und die Aufrufe für die einzelnen Eigenschaften delegieren. Leider könnte man auf dem Client auf die erforderliche Schnittstelle umstellen, aber Sie sollten in der Lage sein zu wählen, welche Eigenschaft Sie verwenden möchten.

EDIT: Nicht sicher über die Schnittstelle auf DTO-Teil ... weiß nicht, ob eine DataContract attributierte Klasse, die Schnittstellen implementiert, auf dem Client mit den Schnittstellen erstellt werden ??!?

    
MotoSV 15.03.2012 21:27
quelle
0

Bitte lesen Sie den folgenden Beitrag

Ссылка

Dies könnte nützlich sein

Ich kopiere den Code für Ihre Referenz

%Vor%     
Amit Bagga 16.03.2012 10:54
quelle
0

Warum verwenden Sie nicht einfach Komposition statt Vererbung? Wenn das nicht klappt, würde PostSharp mehrere Vererbungshilfe?

    
Sentinel 18.03.2012 09:44
quelle

Tags und Links