2011-01-21 14 views
5

私は現在、小さなASP.NET MVCプロジェクトに取り組んでいます。
私はMS Sql Serverデータベース上で持続するためにNhibernateを実装しようとしています。 インターネットで見つかったDDDやその他のプロジェクトを長い時間勉強してきたので、私はリポジトリパターンを検討することに決めました。 今私はジレンマに直面しています。
Nhinbernateを使用する場合、本当にリポジトリが必要ですか?私は昔のを見つけたASP.NET MVC、Nhibernateとsmall/mediumプロジェクト用のリポジトリ

public Domain.Reminder GetById(Guid Code) 
{ 
    return (_session.Get<Domain.Reminder>(Code)); 
} 

public Domain.Reminder LoadById(Guid Code) 
{ 
    return (_session.Load<Domain.Reminder>(Code)); 
} 

public bool Save(Domain.Reminder Reminder) 
{ 
    _session.SaveOrUpdate(Reminder); 
    return (true); 
} 

public bool Delete(Domain.Reminder Reminder) 
{ 
    _session.Delete(Reminder); 
    return (true); 
} 


Nhinbernateはそのようなことを何度も書くことが回避と対話するサービス層を(私は現時点ではサービス層を持っていない)持っている方が良いと思いませんかリポジトリに対するAyendeのPOST。
これらのトピックの周りには巨大な議論があり、その答えは常に...依存していますが、あまりにも多くの抽象レイヤーでは、より複雑で追随が難しいようです。
私は間違っていますか?

+0

ちょっとしたメモです。中小規模のプロジェクトはありませんが、今は小さくても構いませんが、明日のマネージャーはあなたにもう1つのフィーチャーを求め、もう1つのフィーチャーともう1つのフィーチャーを求めます。そして最終的には、 。 Big Design Up Frontが好きではありませんが、時には少し先を考える必要があります。 – goenning

+0

私はあなたに完全に同意しますが、実際には、将来私がnihbernateを使用しないかもしれないという事実のためではないにしても、私はリポジトリを使う利点を見ることができません。私は現時点で正当化できない余分な仕事をたくさん作り出しています。 – LeftyX

答えて

7

Ayendeは、あなたがこの質問をした理由のためにあなたが行ったのと同じ方法でリポジトリを書こうとしていませんでした。繰り返しコードであり、NHはそれをすべて処理できます。彼はあなたがリポジトリと同じようにNHに直接電話することを勧め、それについて心配することはありません。

私は彼にかなり同意します。本当に多くの仕事を除いてはそれほど得策はありません。

+0

これは私が聞きたかった答えであることを告白する必要があります: – LeftyX

0

Repository/DAO/Whateverを使用すべき理由がいくつか見つかりました。

  1. ユニットテスト。私はISessionをモック/スタブしようとしたことはありませんでしたが、Repository/DAOインターフェイスを嘲笑したりスタブしたりするよりもはるかに複雑であるはずです。
  2. コードの再利用。サービス/コントローラにクエリを直接書き込むと、特定のクエリを再利用する必要が生じたときにそのクエリが複製されます。リポジトリにラッパーを持っている場合は、そのメソッドを呼び出すだけです。
  3. Single Responsibility Principle。あなたのコントローラの周りにあなたの質問を広めることは、この原則を破ります。
  4. NHibernate依存性。 OK、これは起こりにくいですが、ORMを変更する必要がある場合、リポジトリによって簡単になります(見た目は簡単、簡単ではありません:))。また、ユーザーのデータソースをデータベースからMicrosoft Active Directoryに変更する必要がある場合でも、それは簡単です。

これは知っているので、他のことは思い出せません。

+0

ありがとうOenning。私はコントローラーではなくサービスレイヤーにクエリを書きたいと思っています。私はそれがビジネスロジックを置くのにも適していると思う。それはUIにはありません。サービスレイヤーを別の場所に接続したい場合は、再利用できます。 Nhibernateの依存関係。まあ、はい、私は同意することができますが、私はすぐにそれが起こると思うし、私はそれがリポジトリを変更することとは異なるとは思わない。とにかくありがとう。 – LeftyX

+0

1. reposを模擬している場合は、「既知の治具」のテストパターンを使用してください。 2.あなたのサービス層に抽象を作成することはできません。これは完全に間違っています。 3.まったくありません。あなたはどこかに電話するつもりです。サービスコールまたはリポジトリコール中かコントローラの一部かは関係ありません。それでも同じコード。コントローラーは依然としてdbの照会を行います。 – jfar

+0

@jfar 1.「既知のフィクスチャ」テストのアンチパターンとは何ですか?聞いたことがない。私は常に私のリポジトリを嘲笑します。 2.あなたの言うことが正しいとすれば、リポジトリと同じデザインになりますが、あなたはそれを別のものと呼ぶでしょう。これの例がありますか?私はこれについていくつかのコードを見たいと思います。 3.コントローラーはdbの照会に責任を負いません。他の人に照会する必要があります。彼は要求を受け取り、それに基づいて他のクラスにタスクを委任し、次のビューを選択する。 – goenning

4

代わりに汎用リポジトリを使用してください。 1クラスあたり1つのリポジトリが簡単に過度に使用される可能性があります。

私は、Get、Load、Saveメソッド、およびさまざまなマッチングメソッド(1つはLinq用、もう1つはドメインクエリ用)で1つのリポジトリを使用します。

最後のメソッドは、ICreateCritiera実装を受け入れます。以下は、インターフェースとその1つの実装です。

public interface ICreateCriteria<T> : ICreateCriteria 
{ 
    DetachedCriteria GetCriteria(); 
} 

public class ChallengesAvailableToRound : ICreateCriteria<Challenge> 
{ 
    private readonly Guid _roundId; 

    public ChallengesAvailableToRound(Round round) 
    { 
     _roundId = round.Id; 
    } 

    public DetachedCriteria GetCriteria() 
    { 
     var criteria = DetachedCriteria.For<Challenge>(). 
      CreateAlias("Event", "e"). 
      CreateAlias("e.Rounds", "rounds"). 
      Add(Restrictions.Eq("rounds.Id", _roundId)); 

     return criteria; 
    } 
} 

これにより、独自のクラスにクエリを分割し、それらをプロジェクト全体に簡単に再利用することができます。

+0

私はケニーあなたの考えが好きです。私はそれに取り組もうとします。ありがとう – LeftyX

+0

ケニー、私はあなたのソリューションが私にとって十分だと思います。ありがとう。 – LeftyX

関連する問題