2012-01-01 8 views
5

私のサービス層が私のリポジトリをどれくらい知っているべきですか?過去のプロジェクトでは、私は常にリストを返し、私が必要としたそれぞれのための方法を持っていました。NHibernateを使用したリポジトリパターン?

したがって、メソッドである5のIDを持つすべての行を返す必要がある場合は、私は作成、更新、削除、および他のNHibernateオプションのための汎用リポジトリを持っていますが、私はそうではありません。

私はそれぞれのケースで非常に多くのメソッドを持つという問題に遭遇し始めたので、IQueryableをもっと使い始めました。

私が特定のIDを持っているすべてを返す必要があった場合、3つのテーブルが必要な場合は、これをロードして新しいメソッドにすることができます。私が特定のIDを必要とし、別の方法であることを熱望していない場合。

where節の部分を実行してIQueryableを返すメソッドであれば、結果を追加することができます(つまり、熱心な読み込みが必要な場合)。

同時に、これによりサービスレイヤーがリポジトリレイヤーを認識するようになりました。これで、サービスレイヤーに特定のNHibernateが存在するようになりました。

私はそれがどのように嘲笑に影響するかもわかりません。

これで、リポジトリが必要な場合は、私がこのルートをダウンすると、混在しているように見えます。

編集

私は私のリポジトリを取り除くと、ちょうど私のサービス層でセッションを持って取得した場合、その後の作業クラスのユニットを有することにポイントはありますか?

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

     } 

答えて

4

誰もがリポジトリの使い方、抽象的なものなどについて意見を持っています。Ayende Rahienにはこの問題に関する良い記事があります:Architecting in the pit of doom: The evils of the repository abstraction layerRepository is the new Singleton。それらはあなたにNHibernateのSessionの上にまだ別の抽象化を作成しようとすべきではない、かなり良い理由を与えます。

+0

私はそれをさらに詳しく見ていきます。私には、サービス層がデータベースについて何も知らないというアイデアが好きです。単体テストを簡単に(必要な場合)ORMを簡単に切り替えることができます。これらのシナリオをどのように扱いますか? – chobo2

+0

私はリポジトリを取り除くのかどうか疑問に思っています。私の作業単位クラスにはポイントがありますか? Edit – chobo2

+0

を参照してください。UnitOfWorkを使用してセッションをラップすることも、NHセッションを直接使用することもできます。ユニットテストに関しては、** Hiberateを使用してユニットテスト用のメモリ内データベースを使用することができます。ここにAyendeの記事があります:http://ayende.com/blog/3983/nhibernate-unit-testing –

2

NHibernateのことは、抽象化しようとしないと、あなたに最大限の効果をもたらします。あなたのサービス層をNHibernateに依存させることは、必ずしも悪いことではありません。セッション、キャッシング、その他のNHibernateの機能を制御できるため、前述の冗長なラッピングコードをすべて省くことはもちろん、パフォーマンスを向上させることができます。

+1

この回答への追加:NHibernateのセッションは、私はリポジトリパターンを使用していない場合は、私が作ったUnitOfWorkクラスにポイントがある場合、私は疑問に思って理由であることのUnitOfWork – ivowiblo

+1

IS? – chobo2

関連する問題