2012-01-01 21 views
5

Mi chiedo quanto dovrebbe sapere il mio livello di servizio del mio repository? Nel passato progetto ho sempre restituito liste e avevo un metodo per ogni cosa di cui avevo bisogno.Pattern di deposito con NHibernate?

Quindi se avessi bisogno di restituire tutte le righe che avevano un Id di 5 sarebbe un metodo. Dispongo di un repository generico per creare, aggiornare, eliminare e altre opzioni di NHibernate ma per le query non lo faccio.

Ora sto iniziando a utilizzare più IQueryable mentre ho iniziato a imbattersi in problemi di avere così tanti metodi per ogni caso.

Dire se avevo bisogno di restituire tutto ciò che aveva un determinato ID e necessario 3 tabelle che dove caricato avidamente questo sarebbe un nuovo metodo. Se avessi bisogno di un certo Id e nessun caricamento avido sarebbe un metodo separato.

Quindi ora sto pensando se metodo I che fa la parte clausola where e restituisco IQueryable quindi posso aggiungere sul risultato (cioè se devo fare il caricamento bisognoso).

Allo stesso tempo, tuttavia, questo rende il livello di servizio più consapevole del livello del repository e non è più possibile cambiare il repository tanto facilmente quanto ora ho NHibernate specifico nel livello di servizio.

Non sono nemmeno sicuro di come ciò possa avere un effetto beffardo.

Così ora mi chiedo se scenderò questa rotta se il repository è necessario poiché ora sembra che si siano fuse insieme.

Modifica

Se faccio a sbarazzarsi di mio repository e solo la seduta nel mio livello di servizio c'è un punto ad avere un'unità di classe di lavoro, allora?

public class UnitOfWork : IUnitOfWork, IDisposable 
    { 
     private ITransaction transaction; 
     private readonly ISession session; 

     public UnitOfWork(ISession session) 
     { 
      this.session = session; 
      session.FlushMode = FlushMode.Auto; 
     } 

     /// <summary> 
     /// Starts a transaction with the database. Uses IsolationLevel.ReadCommitted 
     /// </summary> 
     public void BeginTransaction() 
     { 
      transaction = session.BeginTransaction(IsolationLevel.ReadCommitted); 
     } 

     /// <summary> 
     /// starts a transaction with the database. 
     /// </summary> 
     /// <param name="level">IsolationLevel the transaction should run in.</param> 
     public void BeginTransaction(IsolationLevel level) 
     { 
      transaction = session.BeginTransaction(level); 
     } 

     private bool IsTransactionActive() 
     { 
      return transaction.IsActive; 
     } 

     /// <summary> 
     /// Commits the transaction and writes to the database. 
     /// </summary> 
     public void Commit() 
     { 
      // make sure a transaction was started before we try to commit. 
      if (!IsTransactionActive()) 
      { 
       throw new InvalidOperationException("Oops! We don't have an active transaction. Did a rollback occur before this commit was triggered: " 
                  + transaction.WasRolledBack + " did a commit happen before this commit: " + transaction.WasCommitted); 
      } 

      transaction.Commit(); 
     } 

     /// <summary> 
     /// Rollback any writes to the databases. 
     /// </summary> 
     public void Rollback() 
     { 
      if (IsTransactionActive()) 
      { 
       transaction.Rollback(); 
      } 
     } 

     public void Dispose() // don't know where to call this to see if it will solve my problem 
     { 
      if (session.IsOpen) 
      { 
       session.Close(); 
      } 

     } 

risposta

4

Ognuno ha un'opinione su come utilizzare il repository, cosa astrarre, ecc. Ayende Rahien ha pochi buoni post sul problema: Architecting in the pit of doom: The evils of the repository abstraction layer e Repository is the new Singleton. Quelli ti danno alcuni buoni motivi per cui non dovresti provare a creare un'ulteriore astrazione in cima all'ISession di NHibernate.

+0

Guarderò di più. La cosa che mi interessa è che mi piace l'idea che il livello di servizio non sappia nulla sul database, rendendo più semplice il test dell'unità (se mai ne ho bisogno) e la facilità con cui uscire dagli ORM. come gestisci questi scenari? – chobo2

+0

Mi chiedo anche se mi sbarazzerò dei repository, allora c'è un punto per la mia unità di lavoro? Vedi Modifica – chobo2

+0

Puoi usare UnitOfWork solo per avvolgere la sessione, o anche usare direttamente la sessione di NH. Per quanto riguarda i test di unità, è possibile utilizzare un database in memoria per il test dell'unità ** con ** NHiberate. Ecco un post su di esso da Ayende: http://ayende.com/blog/3983/nhibernate-unit-testing –

2

La cosa di NHibernate è che ti dà la maggior parte se non si tenta di astrarre fuori. Rendere il tuo livello di servizio dipendente da NHibernate non è necessariamente una cosa negativa. Ti dà il controllo su sessioni, memorizzazione nella cache e altre funzionalità di NHibernate, e quindi ti consente di imporove le prestazioni, per non parlare del fatto di averti salvato da tutto il codice di wrapping ridondante che hai menzionato.

+1

In aggiunta a questa risposta: La sessione di NHib è la UnitOfWork – ivowiblo

+1

Ecco perché mi chiedo se c'è un punto nella classe UnitOfWork che ho creato se non utilizzo il pattern di repository? – chobo2