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?
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.
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.
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.
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
anVerweisen Sie auf Ihre DTO-Assembly (stellen Sie sicher, dass sich Ihre DTOs in einer eigenen Assembly befinden) im Client-Projekt
Rufen Sie das Dialogfeld "Dienstreferenz konfigurieren" für den gewünschten WCF-Dienst auf
Aktivieren Sie das Kontrollkästchen "Typen in referenzierten Assemblys wiederverwenden"
Wählen Sie das Optionsfeld "Typen in angegebenen referenzierten Assemblys wiederverwenden"
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.
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 ??!?
Bitte lesen Sie den folgenden Beitrag
Dies könnte nützlich sein
Ich kopiere den Code für Ihre Referenz
%Vor%Tags und Links wcf .net c# web-services dto