Domanda

Ho visto un sacco di domande relative alla mappatura DTOs per oggetti di dominio, ma non mi sentivo hanno risposto alla mia domanda. Ho usato molti metodi prima e avere le mie opinioni, ma sto cercando qualcosa di un po 'più concreto.

La situazione:

Abbiamo molti oggetti di dominio. Stiamo utilizzando un modello Csla modo che i nostri oggetti di dominio possono essere abbastanza complesse e contengono il loro accesso ai dati. Non si vuole far passare questi circa sul filo. Stiamo per essere a scrivere alcuni nuovi servizi che restituirà i dati in diversi formati (.Net, JSON, ecc). Per questo (e altri motivi) stiamo anche creando un oggetto trasferimento dati magra passare intorno sul filo.

La mia domanda è: Come dovrebbe il DTO e oggetto Dominio essere collegati

La mia prima reazione è quella di utilizzare un Fowler, DTO modello-tipo di soluzione . Ho visto fare tante volte e ci si sente giusto per me. L'oggetto di dominio contiene alcun riferimento al DTO. Un'entità esterna (un "mapper" o "assemblatore") è chiamato a creare un DTO da un oggetto di dominio. Normalmente c'è un ORM sul lato dell'oggetto dominio. Il rovescio della medaglia è che il "mapper" tende a diventare estremamente complessa per qualsiasi situazione reale e può essere molto fragile.

Un'altra idea è mettere avanti per l'oggetto dominio per "contenere" il DTO, dal momento che è solo un oggetto di dati magra. Le proprietà oggetto di dominio sarebbero internamente riferimento alle proprietà DTO e può solo restituire il DTO, se richiesto. Vedo problemi con questo, ma ci si sente male. Ho visto alcuni articoli in cui le persone utilizzano NHibernate sembravano utilizzare questo metodo.

Ci sono altri modi? E 'uno dei modi di cui sopra vale la pena usare? Se è così, o se no, perché?

È stato utile?

Soluzione

Un vantaggio di avere un mapper che si trova tra il dominio e la tua DTO non è così appearent quando si stanno sostenendo una sola mappatura, ma come il numero di mappature aumenta, avendo quel codice isolato dal dominio aiuta a mantenere il dominio più semplice e più snella. Non sarà ingombrare il tuo dominio con un sacco di peso in più.

Personalmente, cercare di mantenere la mappatura dei miei entità del dominio e mettere la responsabilità di quello che io chiamo "strato Gestore / servizio". Questo è uno strato che si trova tra l'applicazione e la respository (i), e fornisce la logica di business come il coordinamento del flusso di lavoro (se si modifica A, potrebbe essere necessario modificare anche B quindi il servizio Una lavorerà con servizio B).

Se ho avuto un sacco di possibili formati finendo, potrei cercare di creare un formattatore plugable che potrebbe utilizzare il modello visitatore, ad esempio di trasformare i miei soggetti, ma non ho ancora trovato un bisogno di qualcosa di questo complesso.

Altri suggerimenti

È possibile usare un automapper come quella scritta da Jimmy Bogard che non ha alcun collegamento tra gli oggetti e si basa su convenzioni di denominazione di essere rispettato.

Usiamo modelli T4 per creare le classi di mappatura.

Pro - codice leggibile disponibili al momento della compilazione, più veloce di un mapper runtime. controllo 100% sul codice (può usare parziale modello metodi / template per estendere la funzionalità su base ad hoc)

Con di -. Escludendo alcune proprietà, raccolte di oggetti di dominio, ecc, l'apprendimento della sintassi T4

Un'altra possibile soluzione:. http://glue.codeplex.com

Caratteristiche:

  • mappatura bidirezionale
  • mappatura automatica
  • Mappatura tra i diversi tipi
  • mappatura nidificati e l'appiattimento
  • Le liste e array
  • Verifica dei rapporti
  • Test della mappatura
  • Proprietà, campi e metodi

Come vedi ad implementare un costruttore all'interno della classe DTO che prende come parametro un oggetto di dominio?

Say ... Qualcosa di simile

class DTO {

     // attributes 

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

     // methods
}

Si può anche provare Otis, un mapper oggetto a oggetto. Concetti sono simili a NHibernate mappatura (attributo o XML).

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

posso suggerire uno strumento che ho creato ed è open source ospitato presso CodePlex:. EntitiesToDTOs

Mapping da DTO di entità e viceversa è attuato mediante metodi di estensione, questi compongono il lato Assembler di ciascuna estremità.

Si finisce con il codice come:

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();

Perché non possiamo farlo in questo modo?

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 (o) qualcuno: Si prega di suggerire. Nell'esempio sopra DomainObject è dipende dal DTO. In questo modo posso evitare il codice per fare la mappatura del dto <->. Domainobject

o DomainObject classe può estende la classe DTO?

Un'altra opzione sarebbe quella di utilizzare ModelProjector . Supporta tutti gli scenari possibili ed è molto facile da usare con il minimo ingombro.

Possiamo usare fabbrica, Memento, e builder per questo. Fabbrica nascondere i dettagli su come creare un'istanza di modello di dominio da DTO. Memento prenderà cura la serializzazione / deserializzazione del modello di dominio da / per DTO e può anche accedere ai membri privati. La volontà Builder consente la mappatura da DTO a dominio con interfaccia fluida.

Mantenere la logica di mappatura all'interno della vostra entità significa che l'oggetto di dominio è ora a conoscenza di un "dettaglio implementativo", che non ha bisogno di conoscere. In generale, un DTO è il gateway per il mondo esterno (sia da una richiesta in arrivo o tramite una lettura da un servizio / database esterno). Dal momento che l'entità è parte del tuo Business Logic, è probabilmente meglio per mantenere quei particolari al di fuori del soggetto.

Mantenere la mappatura da qualche altra parte sarebbe l'unica alternativa - ma dove dovrebbe andare? Ho provato l'introduzione di mappatura oggetti / servizi, ma, dopo tutto è stato detto e fatto, sembrava overengineering (e probabilmente era). Ho avuto un certo successo con Automapper e tale per i piccoli progetti, ma strumenti come Automapper vengono con i loro insidie. Ho avuto un po 'piuttosto difficile trovare le questioni relative alla mappature perché mappature di automapper sono impliciti e completamente disaccoppiato dal resto del codice (non come "separazione degli interessi", ma più come un "da dove viene la mappatura dimenticato da Dio vivo") in modo da a volte può essere difficile da rintracciare. Per non dire che Automapper non ha i suoi usi, perché lo fa. Penso solo che la mappatura dovrebbe essere qualcosa che è così evidente e trasparente possibile per evitare problemi.

Invece di creare un livello di servizio di mappatura, ho avuto un sacco di successo tenendo le mappature all'interno dei miei DTOs. Dal momento che sempre puntuale DTOs siedono al confine della domanda, sono possono essere messi a conoscenza del Business Object e capire come mappa da / per loro. Anche quando il numero di mappature scala ad un importo ragionevole che funziona in modo pulito. Tutte le mappature sono in un posto e non c'è bisogno di gestire una serie di servizi di mappatura all'interno del Data Layer, Strato Anticorruzione, o Presentation Layer. Al contrario, la mappatura è solo un dettaglio di implementazione delegato al DTO coinvolto con la richiesta / risposta. Dal momento che in genere serializzatori serializzare solo le proprietà ei campi quando lo stai inviando attraverso il filo, non si dovrebbe incorrere in eventuali problemi. Personalmente, ho trovato questo l'opzione più pulito e posso dire, nella mia esperienza, si scala bene su una grande base di codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top