2012-04-24 10 views
6

Ho un servizio WCF e ho appena creato un DTO per un oggetto business.Oggetti di trasferimento dati: eseguire il mapping in DTO o in oggetto business?

La mia domanda è dove mettere la mappatura tra i due?

A) Nel DTO?

public class PersonDTO 
{ 
    [DataMember] public string Id    { get; set; } 
    [DataMember] public string Name   { get; set; } 

    public void CloneFrom(Person p) 
    { 
     Id = p.Id; 
     Name = p.Name; 
    } 

    public void Populate(Person p) 
    { 
     p.Id = Id; 
     p.Name = Name; 
    } 
} 

o

B) Nel oggetto di business?

public class Person 
{ 
    public string Id    { get; set; } 
    public string Name   { get; set; } 

    public void CloneFrom(PersonDTO dto) 
    { 
     Id = dto.Id; 
     Name = dto.Name; 
    } 

    public PersonDTO GetDTO() 
    { 
     return new PersonDTO() 
     { 
      Id = Id; 
      Name = Name; 
     } 
    } 
} 

Mi piace la separazione degli interessi in A (oggetto di business non è a conoscenza di DTOs), ma preferisco l'incapsulamento di B (senza necessità di esporre le budella degli oggetti di business per DTO).

Mi chiedevo solo se ci fosse un modo standard?

risposta

11

direi che questo richiede una classe separata, in quanto né il BO né il DTO dovrebbero preoccuparsi della loro trasformazione in un'altra classe.

Personalmente utilizzo la libreria di automapper per le trasformazioni di oggetti. Con semplici trasformazioni come nel tuo esempio, la mappatura viene eseguita in una singola riga di codice, anche le trasformazioni complesse sono facili da configurare.

Se si desidera mappare se stessi, è comunque possibile utilizzare i metodi di estensione per mantenere l'implementazione della mappatura separata dalle classi DTO e BO.

+0

Davvero? Se ho intenzione di esporre il mio oggetto business per consentire a una terza classe di eseguire la mappatura, potrei farlo anche nel DTO. Creare un'altra classe mi sembra davvero eccessivo. Darei un'occhiata a automapper, grazie. – GazTheDestroyer

+4

@GazTheDestroyer: un DTO è pensato per il trasferimento di dati e non la trasformazione. Un DTO non deve essere consapevole del suo utilizzo, cioè: mappature. Trasporta i dati e spetta al consumatore utilizzare i dati per qualsiasi scopo, ad esempio: mapparli ad un ViewModel, ad esempio. Siete liberi di aggiungere mappature al DTO, ma a mio modesto parere ciò significa che, sebbene manchi l'uso previsto di un DTO, il DTO non è più un DTO. Nel nostro attuale progetto un repository genera entità. BL riceve le entità, le associa a DTO. Interfaccia utente query BL, ottiene DTO e li mappa a ViewModels (come richiesto). – Nope

1

Suggerisco un livello componente. Dovrebbe essere responsabile per la comunicazione tra il tuo livello aziendale e il tuo livello dati. In questo caso, puoi usarlo per tradurre i tuoi oggetti DTO in Business Objects.

+0

Nella mia esperienza, mentre NetTiers ha alcune buone qualità, lavorare con esso può essere frustrante, vedere http://stackoverflow.com/questions/8220206/whither-nettiers –

+0

@DavidClarke Il riferimento che avevo era principalmente solo per la definizione di uno strato componente. Il link che ho fornito è rotto, quindi lo rimuoverò. :) – Khan

0

La tua preoccupazione è "non è necessario esporre l'intestino dell'oggetto business al DTO" sembra un po 'infondato a meno che non ci sia qualcosa che non viene mostrato nel tuo codice dato che stai accedendo a proprietà pubbliche, ad esempio non al fegato.

Per inciso, invece di avere metodi clone si potrebbe implementare un operatore di cast, invece: MSDN

questo modo si può fare qualcosa di simile: Person p = (persona) myPersonDTO;

+0

Sì, il mio esempio è stato molto semplice. In realtà i miei oggetti business hanno cose private che non voglio esporre per scopi di mappatura. – GazTheDestroyer

+1

Se la roba sulla BO è definita privata/protetta, qualsiasi cosa la usi non la vedrà, quindi non è sicuro quale sarebbe il problema su quel fronte. – Peter