wake-up-neo.net

Best practice per il mapping di DTO all'oggetto dominio?

Ho visto un sacco di domande relative alla mappatura di DTO per Domain Objects, ma non ho sentito che hanno risposto alla mia domanda. Ho usato molti metodi prima e ho le mie opinioni, ma sto cercando qualcosa di un po 'più concreto.

La situazione: 

Abbiamo molti oggetti di dominio. Stiamo utilizzando un modello CSLA in modo che i nostri oggetti di dominio possano essere piuttosto complessi e che contengano il proprio accesso ai dati. Non vuoi passare questi in giro sul filo. Stiamo scrivendo alcuni nuovi servizi che restituiranno i dati in numerosi formati (.Net, JSON, ecc.). Per questo (e altri motivi) stiamo anche creando un oggetto di trasferimento dati snello da passare sul filo. 

La mia domanda è come deve essere collegato il DTO e l'oggetto Dominio?

La mia prima reazione è di usare un Fowler, soluzione tipo-modello DTO . Ho visto questo fatto molte volte e mi sembra giusto. L'oggetto dominio non contiene riferimenti al DTO. Un'entità esterna (un "mapper" o un "assemblatore") viene chiamata per creare un DTO da un Oggetto Dominio. Normalmente c'è un ORM sul lato dell'oggetto dominio. Lo svantaggio di questo è che il "mapper" tende a diventare estremamente complesso per qualsiasi situazione reale e può essere molto fragile. 

Un'altra idea avanzata è che l'oggetto dominio "contenga" il DTO, poiché è solo un oggetto dati snello. Le proprietà dell'oggetto dominio farebbero riferimento internamente alle proprietà DTO e potrebbero semplicemente restituire il DTO, se richiesto. Non vedo problemi con questo, ma mi sembra sbagliato. Ho visto alcuni articoli in cui le persone che usano NHibernate sembravano utilizzare questo metodo.

Ci sono altri modi? Vale la pena usare uno dei modi sopra indicati? Se sì o no, perché?

Grazie per eventuali approfondimenti in anticipo.

66
Brian Ellis

Un vantaggio di avere un mapper che si trova tra il tuo dominio e il tuo DTO non è così apparente quando stai solo supportando una singola mappatura, ma con l'aumentare del numero di mappature, avere quel codice isolato dal dominio aiuta a mantenere il dominio più semplice e snello. Non ingombrerai il tuo dominio con un sacco di peso in più.

Personalmente, cerco di mantenere la mappatura fuori dalle mie entità di dominio e di attribuire la responsabilità a ciò che chiamo "Livello Manager/Servizio". Questo è un livello che si trova tra l'applicazione e il/i riposta/i e fornisce una logica aziendale come il coordinamento del flusso di lavoro (se si modifica A, potrebbe essere necessario modificare anche B in modo che il servizio A funzioni con il servizio B). 

Se avessi molti formati finali possibili, potrei cercare di creare un formattatore plug-in che possa usare il pattern Visitor, ad esempio per trasformare le mie entità, ma non ho ancora trovato il bisogno di qualcosa di così complesso.

34
JoshBerke

Potresti usare un automapper come quello scritto da Jimmy Bogard che non ha alcuna connessione tra gli oggetti e fa affidamento su convenzioni di denominazione rispettate.

22
Garry Shutler

Utilizziamo i modelli T4 per creare le classi di mappatura. 

Pro: codice leggibile dall'uomo disponibile in fase di compilazione, più veloce di un programma di analisi runtime. Controllo al 100% del codice (puoi utilizzare metodi parziali/modello di template per estendere la funzionalità su base ad-hoc)

Contro - escludendo determinate proprietà, raccolte di oggetti di dominio, ecc., Imparando la sintassi T4.

6
SturmUndDrang

Come vedi a implementare un costruttore all'interno della classe DTO che accetta come parametro un oggetto dominio? 

Dì ... Qualcosa di simile

class DTO {

     // attributes 

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

     // methods
}
2
Victor

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

Caratteristiche:

  • Mappatura bidirezionale
  • Mappatura automatica
  • Mappatura tra diversi tipi
  • Mappatura nidificata e appiattimento
  • Elenchi e matrici
  • Verifica delle relazioni
  • Test della mappatura
  • Proprietà, campi e metodi
1
Saly

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

0
user10269

Perché non possiamo fare così?

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 precedente DomainObject dipende da DTO. In questo modo posso evitare che il codice esegua il mapping di dto <-> domainobject.

o la classe DomainObject può estendere la classe DTO?

0
user3767551

Posso suggerire uno strumento che ho creato ed è open source ospitato su CodePlex: EntitiesToDTOs .

La mappatura da DTO a Entity e viceversa è implementata da metodi di estensione, questi compongono il lato Assembler di ciascuna estremità.

Finisci con un 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();
0
kzfabi

Puoi anche provare Otis, un mappatore Object-to-Object. I concetti sono simili alla mappatura di NHibernate (attributo o XML).

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

0
Brian Chavez

Possiamo usare il modello Factory, Memento e Builder per quello. Factory nasconde i dettagli su come creare un'istanza del modello di dominio da DTO. Memento si occuperà della serializzazione/deserializzazione del modello di dominio da/verso DTO e può persino accedere ai membri privati. Il Builder consentirà la mappatura dal DTO al dominio con un'interfaccia fluente.

0
Irwansyah