Frage

Ich habe eine Menge von Fragen zu Mapping im Zusammenhang gesehen DTOs Domain-Objekte, aber ich habe nicht das Gefühl haben, meine Frage beantwortet. Ich habe schon viele Methoden und meine eigene Meinung haben, aber ich bin für etwas ein wenig konkreter suchen.

Die Situation:

Wir haben viele Domain-Objekte. Wir sind mit einem CSLA Modell so unsere Domain-Objekte ziemlich komplex sein können und sie enthalten, ihre eigenen Datenzugriff. Sie wollen nicht, diese um auf den Draht zu übergeben. Wir werden einige neue Dienste zu schreiben, die Daten in einer Reihe von Formaten (.Net, JSON, etc.) angezeigt werden können. Dazu (und aus anderen Gründen) schaffen wir auch ein schlankes, Datentransfer-Objekt übergibt um auf dem Draht.

Meine Frage ist: Wie sollten die DTO und Domain-Objekt verbunden werden

Meine erste Reaktion ist eine Fowler, DTO Muster-Art-Lösung . Ich habe dies getan, viele Male gesehen und es fühlt sich richtig für mich. Das Domain-Objekt enthält keinen Hinweis auf die DTO. Eine Außeneinheit (a „Mapper“ oder „Assembler“) aufgerufen wird eine DTO aus einem Domain-Objekt zu erstellen. Normalerweise gibt es eine ORM auf dem Domänenobjektseite. Die Kehrseite der Medaille ist, dass der „Mapper“ äußerst komplex neigt dazu, für jede reale Situation und kann sehr zerbrechlich sein.

Eine weitere Idee streckt ist für das Domain-Objekt zu „enthalten“, um den DTO, da es Aufgabe nur eine magere Datums ist. Die Domain Objekteigenschaften intern würden verweisen auf die DTO Eigenschaften und konnten nur die DTO zurück, wenn gefragt. Ich kann keine Probleme mit diesem sehen, aber es fühlt sich falsch an. Ich habe einige Artikel zu sehen, wo die Menschen mit NHibernate diese Methode verwenden erschien.

Gibt es andere Möglichkeiten? Ist eine der Möglichkeiten, oben lohnt sich der Einsatz? Wenn dies der Fall oder wenn nicht, warum?

War es hilfreich?

Lösung

Ein Vorteil einen Mapper zu haben, die zwischen Ihrer Domain und Ihrem DTO sitzt, ist nicht so scheinbaren, wenn Sie nur eine einzige Mapping unterstützt, aber als die Anzahl der Zuordnungen zu, dass Code aus der Domäne isoliert, die hilft, die Domäne einfacher zu halten und schlanker. Sie werden nicht Ihre Domain mit vielen zusätzlichen Gewicht werden unübersichtlich.

Ich persönlich versuchen und halten die Abbildung aus meiner Domain-Entitäten und legte die Verantwortung in dem, was ich „Manager / Dienstschicht“ nennen. Dies ist eine Schicht, die zwischen der Anwendung und dem respository (n) und bietet Business-Logik wie Workflow Koordination sitzt (Wenn Sie eine ändern, könnten Sie auch B ändern müssen, um so Service A mit Service B arbeiten).

Wenn ich eine Menge von möglichen End-Formaten habe ich einen steckbaren Formatierer aussehen könnte auf der Schaffung, die die Besucher-Muster verwenden könnte, zum Beispiel meiner Einheiten zu verwandeln, aber ich habe keine Notwendigkeit, noch für irgendetwas diese Anlage erhalten.

Andere Tipps

Sie könnten eine AutoMapper verwenden wie derjenige von Jimmy Bogard geschrieben, die keine Verbindung zwischen den Objekten hat und stützt sich auf die Namenskonventionen eingehalten werden.

Wir verwenden T4-Vorlagen die Mapping-Klassen zu erstellen.

Pro - Menschen lesbarer Code zur Verfügung zum Zeitpunkt der Kompilierung, schneller als eine Laufzeit-Mapper. 100% Kontrolle über den Code (kann Teilmethoden / Schablonenmuster verwendet Funktionalität auf einer Ad-hoc-Basis zu verlängern)

Con -. Ohne bestimmte Eigenschaften, Sammlungen von Domänenobjekten usw., Lernen T4 Syntax

Eine andere mögliche Lösung. http://glue.codeplex.com

Features:

  • Bidirektionale Mapping
  • Automatische Zuordnung
  • Mapping zwischen verschiedenen Typen
  • Nested-Mapping und Abflachen
  • Listen und Arrays
  • Überprüfung der Beziehungen
  • Testen der Zuordnung
  • Eigenschaften, Felder und Methoden

Wie Sie sehen einen Konstruktor in der DTO-Klasse zu implementieren, die ein Domain-Objekt als Parameter übernimmt?

Say ... So etwas

class DTO {

     // attributes 

     public DTO (DomainObject domainObject) {
          this.prop = domainObject.getProp();
     }

     // methods
}

Sie können auch versuchen, Otis, ein Objekt-Objekt-Mapper. Konzepte sind ähnlich wie NHibernate Mapping (Attribut oder XML).

http://code.google.com/p/otis-lib / wiki / Ersteschritte

Ich kann ein Werkzeug schlage ich erstellt und ist Open Source bei CodePlex gehosteten. EntitiesToDTOs

Mapping von DTO zum Entity und umgekehrt durch Erweiterungsmethoden implementiert ist, zusammensetzen diese die Assembler Seite jedes Endes.

Sie enden mit Code wie:

Foo entity = new Foo();
FooDTO dto = entity.ToDTO();
entity = dto.ToEntity();

List<Foo> entityList = new List<Foo>();
List<FooDTO> dtoList = entityList.ToDTOs();
entityList = dtoList.ToEntities();

Warum nicht, dass wir so machen?

class UserDTO {
}

class AdminDTO {
}

class DomainObject {

 // attributes
 public DomainObject(DTO dto) {
      this.dto = dto;
 }     

 // methods
 public function isActive() {
      return (this.dto.getStatus() == 'ACTIVE')
 }

 public function isModeratorAdmin() {
      return (this.dto.getAdminRole() == 'moderator')
 }

}


userdto = new UserDTO();
userdto.setStatus('ACTIVE');

obj = new DomainObject(userdto)
if(obj.isActive()) {
   //print active
}

admindto = new AdminDTO();
admindto.setAdminRole('moderator');

obj = new DomainObject(admindto)
if(obj.isModeratorAdmin()) {
   //print some thing
}

@FrederikPrijck (oder) jemand: Bitte machen. Im obigen Beispiel hängt Domainobject auf DTO ist. Auf diese Weise kann ich den Code vermeiden Abbilden des dto zu tun <->. Domainobject

oder Domainobject-Klasse kann erweitert die DTO-Klasse?

Eine andere Möglichkeit wäre die Verwendung ModelProjector . Es unterstützt alle möglichen Szenarien und ist sehr einfach, mit minimalem Platzbedarf zu verwenden.

Wir verwenden Fabrik, Memento und Builder Muster dafür. Fabrik versteckt die Details, wie beispielsweise das Domänenmodelles von DTO zu erstellen. Memento wird die Serialisierung / Deserialisierung des Domänenmodell zu / von DTO kümmern und können sogar private Mitglieder zugreifen. Der Builder ermöglicht die Zuordnung von DTO zu Domäne mit fließend Schnittstelle.

Halten Sie die Abbildungslogik innerhalb Ihres Unternehmens bedeutet, dass Ihr Domain-Objekt ist jetzt bewusst ein „Implementierungsdetail“ dass es nicht darum zu wissen braucht. Im Allgemeinen wird ein DTO ist Ihr Tor zur Außenwelt (entweder von einer eingehenden Anfrage oder über einen Lesevorgang von einer externen Dienst / Datenbank). Da das Unternehmen Teil der Business-Logik ist, ist es wahrscheinlich am besten, diese Details außerhalb des Unternehmens zu halten.

die Zuordnung Keeping woanders wäre die einzige Alternative sein - aber wo sollte es gehen? Ich habe versucht, Mapping-Objekte / Dienste Einführung aber, nachdem alles gesagt und getan war, schien es wie Overengineering (und wahrscheinlich war). Ich habe einige Erfolge für kleinere Projekte mit AutoMapper und so hatte aber Tools wie AutoMapper mit ihren eigenen Tücken kommen. Ich habe einige ziemlich schwer hatte Probleme Zuordnungen im Zusammenhang zu finden, weil AutoMapper die Zuordnungen implizit sind und vollständig aus dem Rest des Codes entkoppelt (nicht wie „Trennung von Bedenken“, sondern eher wie ein „wo kommt die godforsaken Mapping live“), so dass sie kann manchmal schwierig sein, nach unten zu verfolgen. Um nicht zu sagen, dass AutoMapper nicht seinen Nutzen hat, weil es funktioniert. Ich denke nur, sollte Mapping etwas sein, das so offensichtlich und transparent wie möglich Probleme zu vermeiden.

Statt eine Mapping-Service-Schicht zu schaffen, habe ich innerhalb meiner DTOs meine Mappings viel Erfolg zu halten hatte. Da alway DTOs an der Grenze der Anwendung sitzt, sind sie sich des Business-Objekts gemacht werden und herausfinden, wie von / bis sie abzubilden. Auch wenn die Anzahl der Zuordnungen auf ein vernünftiges Maß skalieren funktioniert es sauber. Alle Abbildungen sind an einem Ort, und Sie haben nicht eine Reihe von Mapping-Dienste innerhalb Ihrer Data Layer, Anticorruption Layer oder Presentation Layer zu verwalten. Stattdessen ist die Abbildung nur ein Detail Umsetzung der DTO delegierte mit dem Request / Response beteiligt. Da Serializer nur im allgemeinen Eigenschaften und Felder serialisiert werden, wenn Sie es über den Draht senden, sollten Sie nicht in irgendwelche Probleme laufen. Ich persönlich habe dies die sauberste Möglichkeit gefunden und ich kann sagen, in meiner Erfahrung, es skaliert gut auf einer großen Code-Basis.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top