2009-03-24 6 views
1

私はNHibernateをかなり新しくしていて、私のリポジトリクラスで奇妙な継承チェインの問題が発生しています。私はGabriel Schenker's FAQを参照として使用しており、彼の例に続いて、私はDAO操作のためのコントラクトを "リポジトリ"クラスで定義するためのインターフェースを作成しています。私が扱っているデータスキーマはかなり広範で、しばらくすると、たくさんのコードを複製していることがわかりました。具体的には、追加、更新、削除、および「GetByID」メソッドは、基本インターフェースに汎用の「EntityType」パラメーターを追加した後もまったく同じでした。だから、例えば、これは、リポジトリ操作のための最も基本的なインターフェイスのようになります。NHibernate - インターフェイスの代わりに機能を提供するために抽象ベースを使用することはできますか?

public interface IBasicRepository<EntityType> where EntityType : class 
{ 
    void Add(EntityType entity); 
    void Remove(EntityType entity); 
    void Update(EntityType entity); 
    EntityType GetByID<IDType>(IDType id); 
} 

は、私はちょうど簡潔にするために、今からAddメソッドについて話しましょう。ジェネリックEntityTypeでは、実装はすべて同じであった:

public void Add(EntityType entity) 
{ 
    using (ISession session = NHUtility.OpenSession()) 
    { 
     using (ITransaction transaction = session.BeginTransaction()) 
     { 
      session.Save(entity); 
      transaction.Commit(); 
     } 
    } 
} 

明らかに、(タイプのわずかな変化で)繰り返し、この同じメソッド本体を入力すると、唯一の迷惑ではない、それは私の本の中で悪いデザインです。そこで私はAdd()の実装を提供するRepositoryBaseという抽象基本クラスを作成しました。私はインターフェースの代わりに抄録を使用しているので、RepositoryBaseを継承しているクラスのインターフェース・チェーンを壊してしまい、インターフェースを使うのが正しいとは思えますが、派生の要約も強制されます。

は ....この安っぽい小さなエンティティの例を使用して....

public class Entity1 
{ 
    public Guid ID { get; set; } 
    public String Name { get; set; } 
} 

... 1は、これを行うことはできません...

public interface IEntity1Repository : RepositoryBase<Entity1> 
{ 
    //Illegal!!!! Bad, naughty programmer! 
} 

...しかし、これは結構です

public abstract class Entity1RepositoryBase : RepositoryBase<Entity1> 
{ 
    public abstract ICollection<Entity1> GetByName(string name); 
} 

これはちょっと気になります。それは動作しますが、特に、この特定のスキーマを持つ継承/実装のチェーンがかなり深く進む可能性があるので、間違った方法で私を擦ります。だから、私の質問は以下の通りだと思う:

  1. 私はただこれについて愚かで腹立っているのだろうか?
  2. 私はここで検討しなければならない異なる/より良いデザインがありますか?私はいくつかの他の例(特にBilly McCafferty's)を見てきました。Schenkerのアプローチは初心者のNHibernatingにとっては最も簡単です。

ありがとうございます。

+0

を、私はそれはそれだ、リポジトリが – Paco

答えて

7

1つのオプションは、次のようになります。そのインタフェースを実装する基本クラスで

public interface IRepository<T> where T: class 
{ 
    void Add(T entity); 
    void Remove(T entity); 
    void Update(T entity); 
    T GetByID<IDType>(IDType id); 
} 

。すなわち:

public interface IProductRepository : IRepository<Product> 
{ 
    // Add extra methods 
} 

public class ProductRepository : RepositoryBase<Product>, IProductRepository 
{ 
    // Implement extra methods 
} 
+0

うんトランザクションおよびセッション管理のための責任を負うことはできないだろう:必要ならば、エンティティの種類ごとに拡張され

public abstract class RepositoryBase<T> : IRepository<T> where T: class { ... } 

。私を解きほぐしてくれてありがとう。私は混乱の中でキーボードに対して頭を叩いていました。 –

関連する問題