2012-08-16 3 views
17

Wir verwenden DTOs als Datenverträge in unserem WCF-Webdienst. Der Zweck dieser DTOs besteht darin, nur die Informationen verfügbar zu machen, die für eine bestimmte API-Methode relevant sind.So organisieren und benennen Sie DTOs, die als Datenverträge in einem WCF-Webdienst verwendet werden

Was ich von euch Jungs suche ist einige Ratschläge zu den Best Practices hier.

Betrachten wir zum Beispiel die folgende einfache Modell:

class Order 
{ 
    int CreatedBy { get; set; } 
    DateTime CreatedOn { get; set; } 
    string Description { get; set; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 

unsere API Unter der Annahme, ermöglicht es einem Verbraucher erstellen, aktualisieren und Get eine Bestellung aufgeben, haben wir die folgenden DTOs erstellt. DataMember- und DataContract-Attribute werden der Einfachheit halber weggelassen.

erstellen Methode: Ein Benutzer nicht die Id und CreatedOn Eigenschaften angeben können, so dass die DTO sieht wie folgt aus:

class CreateOrderData 
{ 
    int CreatedBy { get; set; } 
    string Description { get; set; } 
    string Name { get; set; } 
} 

aktualisieren Methode: Ein Benutzer kann nicht angeben, die Id , CreatedOn und CreatedBy Eigenschaften, so sieht das DTO wie folgt aus:

class UpdateOrderData 
{ 
    string Description { get; set; } 
    string Name { get; set; } 
} 

Get Methode: Ein Benutzer sollte alles für den Orden sehen können, so die DTO wie folgt aussieht:

class OrderData 
{ 
    int CreatedBy { get; set; } 
    DateTime CreatedOn { get; set; } 
    string Description { get; set; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 

meine Fragen So sind hier:

  • Angenommen, es gibt mehr Eigenschaften im Auftragsmodell und viele dieser Eigenschaften werden zwischen den DTOs "Create" und "Update" ausgetauscht. Ist es sinnvoll, diese Klassen von einer gemeinsamen Basisklasse zu erweitern? Wenn ja, sollte der "Get" DTO (OrderData) auch von dieser Klasse ausgehen? Wenn wir das tun, belassen es diese DTOs nicht zu sehr voneinander?

  • Wenn alle Eigenschaften zwischen "Erstellen" und "Aktualisieren" DTOs gemeinsam sind, sollten wir noch zwei verschiedene DTOs erstellen? Wenn ja, warum? Wenn nicht (das ist jetzt nur eine Namensfrage), was sollte das "CreateOrUpdate" DTO heißen, damit sich der Name offensichtlich von dem "Get" DTO unterscheidet?

  • Ist es OK, alle DTOs mit etwas wie "Data" oder "DataObject" oder "Dto" zu suffixieren?

  • Sind wir hier auf dem richtigen Weg? Wenn nicht, wie kann dieser Entwurf besser sein?

Update:

ich glaube ich nicht, das Erbe in DTOs mag, weil die Basisklasse wird auch in der WSDL ausgesetzt werden und der Kunde wird in der Lage sein, es zu sehen und es instanziiert, die schmutzig scheint zu mir (siehe: WCF Serialization with object inheritance?). Wie wäre es mit Interfaces in DTOs, um allgemeine Eigenschaften anstelle von Vererbung zu erzwingen? Da DTOs in ihnen kein Verhalten haben sollten, verlieren wir nicht viel, indem wir die Vererbung ersetzen.

+1

+1 Ich denke, es ist bis zu persönlichen Vorlieben.Wenn ich mich in diesem finde Situation Ich neige dazu, Basisklasse zu gehen oder beides zu einem zu kombinieren und gehe auf den Namen "Upsert". Ich würde jedes Suffix wie die ungarische "dto" -Notation weglassen, da man den Typ leicht identifizieren kann und IMHO besser Namespace verwenden kann 'Project.Data.DataObjects' anstatt Suffix.Nur meine 2 Cent –

+0

Danke für Ihre Antwort Jeremy. Ich stimme zu, dass das meiste persönliche Präferenzen sind, aber ich möchte immer noch, dass jemand diese Fragen und Bedenken bestätigt und einige Argumente zu Best Practices und möglichen Fallstricken vorlegt. Wenn ich es richtig verstehe, sollte Upsert auch bedeuten "update falls vorhanden und insert falls not". Obwohl das ein interessanter Gedanke ist, ist es nicht die Absicht dieser APIs. Die Konsumenten dieser APIs wissen genau, wann sie das Programm einfügen oder aktualisieren müssen. –

Antwort

5

Da dies viel über persönliche Vorlieben ist, ich würde das tun ..

  1. Ich würde eine gemeinsame Basisklasse nicht schaffen, da diese nicht in SOLID L haften würden. Wenn Sie sich Sorgen um DRY machen, können Sie stattdessen eine Aggregation erstellen.

  2. Wenn alle Eigenschaften gemeinsam sind, dann ist es sinnvoll, ein Save zu erstellen, das dieses Objekt übernimmt. Die Dto-Klasse hat eine (n) Schlüsseleigenschaft (en), die angibt, ob es sich um eine bestehende Bestellung handelt.

  3. Ich würde alle mit Dto suffixen, da viele Dto-Klassennamen die gleichen wie Domain-Klassen sind, werden sie verwirrend, da sie in der gleichen Methode zusammen existieren werden. Dann können Sie Ihre DTOs mit Datacontract (Name = „Order“, Namespace = „htp: // ihredomain/..“ schmücken..] Auf diese Weise werden sie zu Außenwelt ausgesetzt werden nach Ihren eigenen Vorlieben

Ich habe in mehreren Projekten, die die gleiche allgemeine Architektur verwenden, verwende ich in der Regel AutoMapper, um dtos zu Domäne zuordnen. Es hat gut für mich gearbeitet!

+0

Ich mag Ihre Vorschläge besonders Ihre Erwähnung des SOLID-Prinzips und der gemeinsamen Basisklasse. In Bezug auf AutoMapper habe ich es in der Vergangenheit verwendet und mochte es, aber da unsere Objekte nicht so komplex sind, verwenden wir Erweiterungsmethoden für die Konvertierungen. –