2009-10-07 6 views
5

Sono nuovo di NHibernate (e ORMS) e sto cercando di venire a capo della miriade di diverse opzioni che presenta. Per riferimento, sto utilizzando Fluent NHibernate con oggetti business separati che a loro volta utilizzano DTO esclusivamente per l'accesso ai dati. La mia architettura dell'applicazione deve supportare sia i "front-end" di Windows che quelli web.Il migliore approccio per la costruzione di DTI NHibernate

Il mio dilemma è un approccio generale in quanto sembrano esserci tante opzioni. Il mio DTO ha un aspetto simile al seguente esempio. Ogni DTO ha un riferimento a una ISessione che viene passata loro dalla BO. Essi sono responsabili del proprio carico e risparmia:

public class EmployeeDTO... 

    // Data Properties to be persisted to the database 
    public virtual int Id { get; private set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual ISession Session { get; set; } 

    // Save logic 
    public virtual void Save() 
    { 
     var transaction = Session.BeginTransaction(); 
     Session.SaveOrUpdate(this); 
     transaction.Commit(); 
    } 

    // Load logic 
    public virtual void Load(int id)... 

Prima di tutto: È questo l'approccio corretto a prendere - se il DTO avere la possibilità di salvare e caricare se stesso?

In secondo luogo: Indipendentemente da dove Save/codice di carico si trova, è necessario utilizzare lo stesso ISession per tutta la vita o di un oggetto, o dovrebbero avere un ref al ISessionFactory e apre una nuova sessione ogni interazione del database volta è obbligatorio?

// Open a new session every time I interact with the repository 
    var session = FluentSupport.SessionFactory.OpenSession(); 
    var transaction = Session.BeginTransaction(); 
    Session.SaveOrUpdate(this); 
    transaction.Commit(); 
    session.Close(); 
    // Close the session when I'm done 

Naturalmente c'è sempre l'opzione 3, nessuna delle precedenti :)

+0

Quando un oggetto sa come salvare se stesso viene chiamato DAO, questo non ha nulla a che fare con DTO –

risposta

10

In generale, DTOs non contengono comportamento (come Save, Load) e non contengono conoscenza del modo in cui vengono persistevano (ISession). Sembra che quello che stai creando sia un livello dati. Neanche il tuo livello aziendale dovrebbe conoscere l'ISession. Detto questo, puoi abbinare questa stratificazione a tutto ciò che vuoi in base alle tue esigenze, ma sarà probabilmente difficile passare a un ORM diverso in seguito, se il tuo ORM sanguina attraverso tutti i tuoi livelli.

Per la gestione a vita di ISession, è necessario decidere se si intende utilizzare il modello UnitOfWork, che in pratica dice che ogni richiesta utente ottiene una nuova ISessione. Ci sono anche altre opzioni per la vita dell'ISession e in questo senso non sei limitato. Spesso, ci possono essere le migliori pratiche relative alle app Web rispetto alle app Windows rispetto a qualsiasi altro tipo di applicazione, ma non hai specificato quale stavi scrivendo.

+0

l'architecure deve supportare sia web (Silverlight) che Windows (WPF) – Steve

+0

Ho chiarito la domanda per coprirlo. .. – Steve

2

L'ISession è molto economico da aprire/chiudere. Il problema di tenerlo aperto troppo a lungo è che il pool di connessioni non può riutilizzare la connessione finché non scade o no. Questo potrebbe essere un problema in un'applicazione multiutente.

Nel vostro scenario probabilmente opterei per un approccio orientato al servizio per archiviare i dati di recupero. il che significa che il DTO sarà usato solo internamente all'interno dei confini del servizio. Se hai bisogno di copiare oggetti che sembrano uguali, ti suggerisco di dare un'occhiata a AutoMapper che è stato creato per questo scopo specifico. Se hai un progetto solo Windows o solo web allora non è un problema. È quando ti mescoli. Non è possibile gestire le sessioni nello stesso modo in un'applicazione Windows come in un'app Web.

9

Tenere il codice di caricamento/salvataggio separato dai DTO. Gli oggetti DTO sono solo visualizzazioni dei dati sottostanti.

Quando si eseguono le query, restituire i DTO utilizzando una trasformazione. Qualcosa del genere:

resultSet = session.CreateCriteria(typeof(MyDataObject)) 
    .Add(query criteria, etc.) 
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>()) 
    .List<IMyDTOObject>()
+0

Quali criteri posso utilizzare in Aggiungi metodo (per collegare la proprietà del dominio alla proprietà DTO)? –

+0

@SilvioDelgado: Mi dispiace, non ho lavorato con NHibernate in oltre 3 anni, quindi non lo so. –

+0

Nessun problema. Grazie lo stesso. :) –

3

I DTO sono pensati per essere "oggetti di trasferimento dati". Cioè, oggetti stupidi usati per trasmettere valori o raccolte di valori nel tuo sistema. Non dovrebbero essere responsabili per la persistenza di se stessi, o persino mappare 1-1 agli oggetti di dominio nel tuo livello di dominio.