2012-08-16 10 views
17

Utilizziamo DTO come contratti di dati nel nostro servizio web WCF. Lo scopo di questi DTO è esporre solo le informazioni rilevanti per un metodo API specifico.Come organizzare e denominare DTO che vengono utilizzati come contratti di dati in un servizio Web WCF

Quello che sto cercando da voi ragazzi è qualche consiglio sulle migliori pratiche qui.

Ad esempio, si consideri la seguente semplice modello:

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

Supponendo che la nostra API permette al consumatore di Creare, Aggiornamento e Ottenere un Ordine, abbiamo creato le seguenti DTOs. Gli attributi DataMember e DataContract vengono eliminati per semplicità.

Crea metodo: Un utente non può specificare il Id e createdOn proprietà, in modo che il DTO è simile al seguente:

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

Aggiornamento metodo: Un utente non può specificare il Id , CreatoOn e CreatedBy proprietà, quindi il DTO è simile al seguente:

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

Get metodo: un utente dovrebbe essere in grado di vedere tutto per l'Ordine, in modo che il DTO è simile al seguente:

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

Così qui sono le mie domande:

  • Supponendo che ci siano più proprietà nel modello Ordine e molte di queste proprietà sono condivise tra DTO "Crea" e "Aggiorna", ha senso che queste classi si estendano da una classe base comune? Se sì, il DTO "Get" (OrderData) dovrebbe estendersi anche da quella classe? Se lo facciamo, non lascia questi DTO troppo dipendenti l'uno dall'altro?

  • Se tutte le proprietà sono comuni tra "Crea" e "Aggiorna" DTO, dovremmo creare ancora due DTO diversi? Se sì, perché? Se no, (questa è solo una domanda di denominazione ora) che cosa dovrebbe essere chiamato il DTO "CreateOrUpdate" in modo che il nome sia ovviamente diverso dal DTO "Get"?

  • È OK per suffrare tutti i DTO con qualcosa come "Dati" o "DataObject" o "Dto"?

  • Siamo sulla strada giusta qui? In caso contrario, come si può rendere questo design migliore?

Aggiornamento:

Penso che non mi piace l'eredità nel DTOs perché la classe di base sarà inoltre esposto nel WSDL e il cliente sarà in grado di vederlo e un'istanza che sembra sporca a me (vedi questo: WCF Serialization with object inheritance?). Che ne dici di utilizzare le interfacce in DTO per applicare proprietà comuni anziché ereditarietà? Dal momento che le DTO non dovrebbero avere alcun comportamento in esse, non stiamo perdendo molto sostituendo l'ereditarietà.

+1

+1 Penso che sia preferibile. situazione tendo ad andare in classe base o combinare entrambi in uno e andare per il nome 'Upsert'. Non lascerei alcun suffisso come la notazione ungherese 'dto' poichè puoi facilmente identificare il tipo e IMHO è meglio usare namespace come 'Project.Data.DataObjects' piuttosto che suffisso. Solo i miei 2 centesimi –

+0

Grazie per la tua risposta Jeremy. Sono d'accordo che la maggior parte di esso è una preferenza personale, ma vorrei comunque che qualcuno convalidi queste domande e preoccupazioni e presenti alcuni argomenti riguardanti le migliori pratiche e possibili insidie. Inoltre, se ho capito bene, Upsert dovrebbe significare "aggiorna se presente e inserisci se non". Anche se questo è un pensiero interessante, non è questa l'intenzione di queste API. I consumatori di queste API sapranno in modo specifico quando inserire o aggiornare. –

risposta

5

Poiché si tratta di molto di preferenze personali, vorrei fare questo ..

  1. non vorrei creare una classe base comune dal momento che non sarebbe aderire a L in solido. Se sei preoccupato per DRY, allora potresti creare un'aggregazione.

  2. Se tutte le proprietà sono comuni, ha senso creare un Salvataggio che prende quell'oggetto, l'ordine in cui la classe Dto avrà una proprietà chiave (i) che indicherà se è un ordine esistente o meno.

  3. Avrei suffisso tutto con Dto, poiché molti nomi di classe Dto sono uguali a quelli delle classi di dominio, si confondono poiché saranno presenti nello stesso metodo insieme. Poi si può decorare la vostra DTOs con DataContract (Name = "Ordine", Namespace = "htp: // yourdomain/.."..] In questo modo saranno esposti al mondo esterno in base alle proprie preferenze

Sono stato in più progetti che utilizzano la stessa architettura generale, in genere utilizzo AutoMapper per mappare da dtos a dominio. Ha funzionato perfettamente per me!

+0

Mi piacciono i tuoi suggerimenti, in particolare la tua menzione del principio SOLID e della classe base comune. Per quanto riguarda AutoMapper, l'ho usato in passato e mi è piaciuto, ma dal momento che i nostri oggetti non sono così complessi, stiamo usando metodi di estensione per le conversioni. –

Problemi correlati