2009-03-16 6 views
8

Ho una classe di repository che definisce alcuni metodi Get/Save/Delete di base. All'interno di questi, utilizzo NHibernate per eseguire il lavoro sulle mie entità aziendali. Per esempio:Il modo migliore per utilizzare NHibernate con il modello di repository

Public Class SecurityRepositoryNHibImpl : Implements ISecurityRepository 
    Public Function GetUser(ByVal UUID As System.Guid) As Entities.User Implements ISecurityRepository.GetUser 
     Dim eUser As Entities.User 
     Using session As ISession = NHibernateHelper.OpenSession() 
      eUser = session.Get(Of Entities.User)(UUID) 
     End Using 
     Return eUser 
    End Function 
End Class 

Tuttavia, sulla mia classe User ho alcune proprietà e le collezioni di altri oggetti che Idealmente mi piacerebbe essere caricato in modo pigro. Ma ovviamente, l'ISession è creata e disposta all'interno del repository, il che credo sia il motivo per cui, al di fuori di questo, quando provo ad accedere a quelle proprietà ottengo un errore "Impossibile inizializzare il proxy - nessuna sessione".

La mia unica opzione è quindi disabilitare il caricamento lento quando si utilizzano i repository? O è possibile (o semplicemente sciocco) in qualche modo ottenere la sessione in ambito nel livello aziendale?

Mi piace il modello di repository e NHibernate sta crescendo su di me (dopo molte frustrazioni iniziali che cercano di farlo funzionare), quindi qual è il modo migliore in cui i guru hanno scoperto di usarli insieme?

Sono abbastanza nuovo di NHibernate e dei modelli di repository in generale (al lavoro usiamo ancora principalmente VB6!), Quindi perdona quella che potrebbe essere una domanda stupida. Grazie.


@mookid: Grazie amico, è davvero utile ma potrei lasciarlo aperto ancora un po '. È il back-end di un servizio web WCF, e tutte le funzioni saranno a livello di chiamata, in modo che una sessione per ogni chiamata-vita sarà buona. Non sono proprio sicuro di come ottenere una cosa del genere funzionando nel livello aziendale, idealmente non voglio che gli oggetti business debbano interfacciarsi direttamente con le classi di NHibernate. Immagino che una specie di wrapper per la sessione di NHibernate lo riassuma almeno ... Hmm, mi hai messo sulla strada giusta almeno.


simile alla parola chiave qui è "unità di lavoro", per il quale una tonnellata di risorse esiste sul web in relazione alla NHibernate. In particolare cerca Ayende's implementation in Rhino Commons e il suo webcast App Architecture (no. 9 at Hibernating Rhinos), molto informativo. Inizialmente ero confuso perché pensavo di mettere una "Unità di lavoro" nello scenario aziendale mescolando preoccupazioni, but I was soon corrected.

risposta

12

Creare la tua ISession e smaltirlo esplicitamente all'interno dei tuoi repository come se fosse ok per progetti piccoli e molto semplici - ma, come hai scoperto, è breve quando inizi a voler utilizzare alcune delle fantastiche funzionalità supportate da NHibernate.

Probabilmente dovresti lasciare che lo stile di vita della sessione sia controllato da qualcosa al di fuori dei tuoi repository - ad es. se stai facendo applicazioni web ASP.NET, potresti voler salvare la sessione nella richiesta corrente (HttpContext.Current.Items se ricordo correttamente) per la durata della richiesta web, quindi eseguire il commit e lo smaltimento alla fine della richiesta (o rollback se si verifica un'eccezione).

Non conosco il modo migliore per controllare lo stile di vita della sessione nelle applicazioni ASP.NET, ma deve esserci un modo per fare in modo che il codice venga chiamato all'inizio e alla fine di ogni richiesta. In ASP.NET MVC può essere facilmente ottenuto derivando tutti i controller da un controller di base che ha sostituito i suoi metodi OnActionExecuting e OnActionExecuted.