2009-08-24 12 views
6

ho lavorato con successo con linq2sql ei DTOs LINQ (le classi che vengono creati da linq2sql) ....Confusione tra DTO (linq2sql) e oggetti di classe!

Sono confuso, ho il compito di aggiornare una vecchia applicazione e posso vedere che i miei DTOS verrà utilizzato come dovrebbero essere .... per il trasporto data

Sto utilizzando il modello di repository così sto passando i dati dal repository al servizio tramite il dtos linq2sql ... una volta sono nel livello di servizio (questa è fondamentalmente la mia logica di business) quindi ho bisogno di passare oggetti di classe ..

questi oggetti di classe sono fondamentalmente un'immagine speculare (più o meno) del dtos - ci sono così mi cambia in qualche posto ma generalmente lo stesso ..

Quindi tornando alla domanda in mano! - questa buona pratica è quella di usare dtos solo per trasportare dati dal repository al livello di servizio ... e una volta nel livello di servizio (business logic) dovrei ma MAPPING tutti i miei dtos alle parti del contatore dell'oggetto class (ovviamente usando automapper! !)

La mia altra alternativa è continuare a utilizzare gli oggetti di classe come DTOS e passarli da metodo a metodo e come tipi di ritorno ecc. Ma ritengo che questa sia una cattiva pratica e continuo a girare in tondo chiedendomi quale metodo dovrebbe applicarsi?

Qualsiasi aiuto molto apprezzato

grazie

risposta

5

Ecco il mio parere: Quando si tratta di tutte le applicazioni non-banale. Usare i tuoi oggetti linq2Sql come modello di dominio è una pessima idea. Vedo linq2Sql come un ORM e nient'altro. I database (a cui linq2Sql ha una corrispondenza diretta) è una normalizzazione dei dati . Le classi (nel senso OOAD) sono una normalizzazione del comportamento (non dati).

[questi oggetti di classe sono basicaly immagine speculare] ...

ho incontrato questo quando la creazione di applicazioni con Linq2Sql. Siamo realistici .... la maggior parte delle applicazioni aziendali sono glorificate applicazioni CRUD. Quindi non è fuori discussione che una grande percentuale delle entità della tua applicazione corrisponderà direttamente alle tabelle del database. Non volevo essere associato direttamente agli DTO che sono stati generati, ma allo stesso tempo non volevo che le classi duplicate fossero disseminate nella mia applicazione.

Quindi ecco la mia soluzione:
I "programmato su un'interfaccia".

Diciamo che ho un PersonDto (Dto per oggetto Data Transfer) con proprietà di FirstName, LastName, Age (che si riferiscono direttamente alle colonne del database).

Ho creato un'interfaccia IPerson e il mio PersonDto l'ha implementato.

 

    [Table(Name="Persons")] 
    internal class PersonDto : IPerson 
    { 
     .... 
    } 
 

E il mio metodo repository avrebbe preso in e recuperare IPerson in contrapposizione alla classe Linq2Sql.

 

    IPerson somePerson = _repository.Get(someGuid); 
    somePerson.FirstName = "SomeName"; 
    _repository.Save(somePerson); 
 

Questo approccio ha funzionato molto bene per me. Ogni volta che sento di dover deviare dal DTO, posso farlo abbastanza facilmente a causa dell'interfaccia che rappresenta il mio oggetto rispetto al DTO.

Alcuni puntatori generali: Costruisci il tuo DTO a mano ... So che sembra pazzesco, ma troverai che funziona molto bene con un approccio di sviluppo guidato dall'alto verso il basso. Gli oggetti del tuo DTO (linq2Sql) saranno estremamente leggeri e saranno aperti alle modifiche al di fuori del designer .dbml.

Mantenere del DTO e DataContext di interno. Non c'è motivo per cui i tuoi dto vengano esposti pubblicamente (dato che hai interfacce pubbliche per i tuoi repository e oggetti di dominio). Ciò comporterà una separazione logica tra il modello di dominio e l'accesso ai dati.

Mettere tutto il livello di accesso ai dati in un progetto separato (di nuovo per rafforzare questa separazione).

Inserisci le dichiarazioni dell'interfaccia in un progetto separato (questo ti assicura di non incorrere in riferimenti circolari).

Spero che questo aiuti ...

+0

Mi piace questa idea ... l'unico problema è in MVC, i controller non possono utilizzare le interfacce per i metodi di aggiunta. Ciò rende le interfacce relativamente inutili per MVC. Come hai gestito questo problema, perché mi piacerebbe davvero farlo. –

+0

aggiungi metodo? puoi elaborare, sto usando questo appraoch con aspmvc e non ho avuto problemi. – Amir

+0

"i controller non possono utilizzare le interfacce per i metodi di aggiunta", è sufficiente creare un modello di visualizzazione che implementa l'interfaccia. Può risiedere nel progetto web in quanto è solo un oggetto che aiuta a facilitare le interazioni con la vista. – Amir

2

Questo è uno dei migliori discussioni del tema che ho visto:

http://blog.wekeroad.com/blog/linqtosql-momma-said-knock-you-out/

Nelle decisioni finali, di accoppiamento e di coesione sono situazionali e devi decidere cosa è meglio per la tua situazione.

Quando la tua applicazione supera LinqToSql, quanto sarà facile strappare LinqToSql e inserire un altro ORM nella sua posizione? Questo è qualcosa su cui devi riflettere seriamente.

In generale, ridurre al minimo le conoscenze del livello aziendale relative a LinqToSql. LinqToSql dovrebbe essere completamente nascosto dal tuo livello di interfaccia utente (il tuo livello aziendale costituisce una buona parte di questo scudo). Con LinqToSql è molto semplice seguire il percorso architetturale sbagliato e può essere molto difficile tornare sulla giusta strada dopo il fatto.

0

Le classi generate dal designer linq2sql sono classi parziali, quindi è possibile estenderle e inserire la logica aziendale direttamente in esse. L'idea è che linq sia usato per persistere/ricostruire queste entità in modo da poter evitare il tipo di mappatura di cui stai parlando.

+1

Una volta che si inizia a incorporare la logica di business nelle classi parziali LinqToSql, è molto difficile da separare in un secondo momento. Se non vuoi/hai bisogno di un livello aziendale, va bene, ma non è sempre la strada giusta da percorrere. Inoltre, è difficile sostituire LinqToSql con un ORM diverso con un set di funzionalità diverso in futuro (che potrebbe essere o non essere necessario). –

+0

Il punto è che le entità linqToSql fanno parte del 'livello aziendale' e il repository viene utilizzato per recuperarle/persisterli nella base dati. Sì, c'è un po 'di accoppiamento con il progettista linq, ma questo è un problema diverso. – Lee

+0

@Lee: no, non dovresti usare linq2sql per il tuo livello aziendale. È un MERAVIGLIOSO mappatore relazionale di oggetti, ma ti incoraggio fortemente a non cadere in quella trappola. Il tuo database è una normalizzazione dei dati, il tuo livello aziendale è una normalizzazione dei comportamenti. – Amir

3

In realtà avevo una domanda simile su questo argomento sebbene il mio intento fosse leggermente diverso. La raccomandazione era di usare le classi Linq2SQL come oggetti di dominio e di sfruttare le classi parziali come altri hanno menzionato. La mia preoccupazione principale è stata la forma di quegli oggetti (cioè i nomi di proprietà) e l'accessibilità dei membri della classe (ad esempio, la privacy privata protetta ad esempio).

La forma degli oggetti e persino l'accessibilità possono essere risolti utilizzando i modelli t4 in cui Damien Guard ha messo insieme un modello T4 per consentire di controllare la forma delle classi che Linq2Sql genererebbe per te. Questo può essere visto qui T4 template for Linq2SQL.

Questo è l'approccio che ho intenzione di guardare in e vedere se affronta le mie preoccupazioni. Inoltre, se il tuo livello di servizio può accettare interfacce con gli argomenti del metodo, puoi anche controllare a cosa ha accesso il livello di servizio tramite i wrapper di interfaccia attorno ai tuoi DTO Linq2SQL.

Spero che questo aiuti.