ジェネリックを使用してエンティティのリポジトリを取得するために、次の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();
}
}
ただし、1 つのエンティティに対して UnitOfWork を個別にインスタンス化する 2 つの別個のクラスがあるという問題に遭遇しました。つまり、そのエンティティに対して 2 つのリポジトリが作成されます。これにより、エンティティを保存しようとすると、エンティティ フレームワークで「エンティティ オブジェクトを IEntityChangeTracker の複数のインスタンスで参照することはできません」というエラーがスローされるという問題が発生します。
リポジトリがプライベート フィールドに格納され、存在する場合は再利用されるか、null の場合は作成される「作業単位クラスの作成」セクションの下で、Tom Dykstra によるこの投稿で説明されているように、UOW パターンにもっと厳密に従う必要があると考えています。これに関して私が抱えている問題は、UOW で引き続きジェネリックを使用Repository<T>
することであり、コード内のすべてのエンティティ タイプに対してプライベート リポジトリ フィールドを宣言する必要はありません。
特定のタイプのリポジトリがすでにインスタンス化されているという事実を保存し、その新しいインスタンスを作成する代わりにそれを再利用するにはどうすればよいでしょうか?
--- 編集: これが修正です ---
Ninject を使用して、次のように指定して、リポジトリと UOW の両方のインスタンスを 1 つだけインスタンス化するようにバインディングを調整しました。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();