2012-04-18 11 views
3

genericsを使用して自分のエンティティのリポジトリを取得するには、次のUnitOfWorkクラスを使用しています:クラス。UnitOfWork内の汎用リポジトリへの参照を保存する

public class UnitOfWork : IUnitOfWork 
{ 
    private readonly EfDbContext _context; 

    public UnitOfWork() 
    { 
    _context = new EfDbContext(); 
    } 

    public IRepository<T> RepositoryFor<T>() where T : Entity 
    { 
    return new Repository<T>(_context); 
    } 

    public void Save() 
    { 
    _context.SaveChanges(); 
    } 
} 

しかし、私はそのエンティティのための2つのリポジトリが作成されることを意味し、単一のエンティティのための独立したUnitOfWorkのインスタンスを二つの別々のクラスを持っているいくつかの問題に実行しています。これにより、エンティティを保存しようとすると、 "エンティティオブジェクトが複数インスタンスのIEntityChangeTracker"で参照されないという問題が発生します。

私はリポジトリはプライベートフィールドに格納して再利用する既存の場合は作成された「ワーク・クラスのユニットの作成」セクションの下に、この post by Tom Dykstraで説明したように、私はより密接UOWパターンをたどる必要があると考えています

nullの場合私がこれを持っている問題は、私がUOWにジェネリック(Repository<T>)を使い続け、自分のコードにあるすべてのエンティティタイプのプライベートリポジトリフィールドを宣言する必要がないことです。

特定のタイプのリポジトリが既にインスタンス化されているという事実を保存し、そのインスタンスを新規に作成する代わりに再利用するにはどうすればよいですか?

---編集:ここでは修正---唯一のリポジトリとUOWの両方の単一のインスタンスをインスタンス化するために、私は私のバインディングを調整Ninjectを使用して

InRequestScope

kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope(); 
//kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope(); // Removed based on comment below 
kernel.Bind(typeof(EfDbContext)).ToSelf().InRequestScope(); 
+0

シングルトン、またはリポジトリへの参照を保持し、参照またはコピーまたはそのリポジトリを提供するファクトリ – Prescott

+1

場合によっては、Include()を使用して特定のクエリを作成したい場合は、汎用リポジトリ十分ではありません。汎用リポジトリを継承する特定のエンティティタイプのリポジトリが必要な場合があります。 –

+0

完全性の問題として、リポジトリ<>をIoCコンテナに登録しないでください。これは作業単位の一部であり、UoWインスタンス以外の何らかの理由で取得することは許されません。さらに、コンテナから解決するのではなく、明示的にインスタンス化します。したがって、それをコンテナに登録することは意味をなさない。 –

答えて

2

を指定してい問題は複数のリポジトリではなく、複数のDbContextインスタンスにあります。 EFでは、複数のコンテキストに同じエンティティインスタンスを一度に追加することはできないことを示しています。リポジトリを共有することは役に立ちません。さらに、複数のUoW共有シングルトンリポジトリを持つことは、地獄への道です。あなたが使用するように仕事の

  1. 株式ユニット:あなたがいずれかを行う必要があり、問題を解決するには

    など、(EFはスレッドセーフではありません)同時実行を処理するために、状態は非常に困難になります単一のビジネスオペレーションでUoWの同じインスタンス(およびDbContext)を追加します。

  2. エンティティインスタンスのコピーを作成して別のUoWに追加します。

この選択は、状況によって異なります。

+0

ありがとうパベル...あなたのコメントは正しい方向に私を指摘した。私はその問題を発見した。 Ninjectを使用してInRequestScopeを追加し、問題を修正しました。私は実際の解決策で質問を更新しました。私は正しい方向に私を指していただきありがとうございます。 – bigmac

+0

このアプローチは通常正常に動作します。ただし、特定の制限があります。たとえば、最終的には、単一のサーバーメソッドで異なるUoW(異なるトランザクション)を使用する必要があります。そのような場合は、UoW共有の正確な制御のために要求スコープの代わりにパラメータ化を使用することを検討してください。 –

関連する問題