2012-01-01 12 views
5

Zastanawiam się, ile powinna moja warstwa usługi zna moje repozytorium? W poprzednim projekcie zawsze zwracałem listy i miałem metodę dla każdej rzeczy, której potrzebowałem.Wzór repozytorium z NHibernate?

Więc jeśli potrzebowałem zwrócić wszystkie wiersze, które miały identyfikator 5, który byłby metodą. Mam ogólne repozytorium dla tworzenia, aktualizacji, usuwania i innych opcji NHibernate, ale w przypadku zapytań nie mam.

Teraz zaczynam używać więcej IQueryable, ponieważ zacząłem borykać się z problemami mającymi tak wiele metod dla każdego przypadku.

Powiedz, czy muszę zwrócić wszystko, co miało określony identyfikator i potrzebowałem 3 tabel, w których spodziewano się załadowania tej nowej metody. Gdybym potrzebował pewnego Id i nie ma chętnego ładowania, który byłby osobną metodą.

Tak więc teraz myślę, że jeśli I metoda, która robi część klauzuli where i zwracają IQueryable, to mogę dodać wynik (tj. Jeśli muszę zrobić chętny ładowanie).

Jednocześnie jednak powoduje to, że warstwa usług jest bardziej świadoma warstwy repozytorium i nie mogę już przełączać repozytorium tak łatwo, jak teraz mam określony NHibernate w warstwie usługi.

Nie jestem również pewien, jak to wpłynęłoby na kpiny.

Teraz zastanawiam się, czy pójdę tą drogą, jeśli potrzebne jest repozytorium, ponieważ wygląda na to, że zostały połączone razem.

Edit

Gdybym pozbyć mojego repozytorium i po prostu mieć sesję w moim warstwie usług jest tam punkt o jednostkę klasy roboczej wtedy?

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(); 
      } 

     } 

Odpowiedz

4

Każdy ma opinię, jak korzystać z repozytorium, co streszczenie itp. Ayende Rahien ma kilka dobrych postów na temat problemu: Architecting in the pit of doom: The evils of the repository abstraction layer i Repository is the new Singleton. Dają ci całkiem niezłe powody, dla których nie powinieneś próbować tworzyć kolejnej abstrakcji na szczycie ISiS NHibernate.

+0

Będę się w to bardziej interesować. Rzecz, która mnie dopada, podoba mi się pomysł, że warstwa usługowa nie wie nic na temat bazy danych, co ułatwia testowanie jednostki (jeśli kiedykolwiek zajdzie taka potrzeba) i łatwą zmianę ORM. jak sobie radzisz z tymi scenariuszami? – chobo2

+0

Zastanawiam się również, czy pozbywam się repozytoriów, czy istnieje punkt do mojej klasy jednostek pracy? Zobacz Edycja – chobo2

+0

Możesz użyć UnitOfWork tylko po to, aby otoczyć sesję, lub nawet bezpośrednio z sesji NH. Jeśli chodzi o testowanie jednostek, możesz użyć bazy danych w pamięci do testowania jednostek ** z ** NHiberate. Oto post na ten temat od Ayende: http://ayende.com/blog/3983/nhibernate-unit-testing –

2

Rzeczą o NHibernate jest to, że daje ci najwięcej, jeśli nie próbujesz tego streścić. Uczynienie warstwy usługowej zależne od NHibernate niekoniecznie jest czymś złym. Zapewnia kontrolę nad sesjami, pamięcią podręczną i innymi funkcjami NHibernate, a tym samym umożliwia obniżenie wydajności, nie wspominając już o oszczędzaniu cię z całego zbędnego kodu zawijania, o którym wspomniałeś.

+1

Dodając do tego odpowiedź: Sesja NHibernate IS UnitOfWork – ivowiblo

+1

Dlatego właśnie zastanawiam się, czy istnieje punkt do klasy UnitOfWork, którą zrobiłem, jeśli nie używam wzorca repozytorium? – chobo2