ASP.NET MVC 4で、EntityFrameworkを使用してMSSQLServerと通信する比較的単純なWebアプリケーションを構築しています。将来的にアプリケーションを拡張する余地はたくさんあるので、後で作業を節約するために、コードの再利用性と適応性を最大化するパターンを目指しています。アイデアは次のとおりです。
- 作業単位パターン。各アクションセットの最後に変更をコミットするだけで、データベースの問題を保存します。
BaseRepository<T>
リポジトリはほとんど同じであるため、一般的なリポジトリを使用します。奇妙な例外は、その追加のメソッドを拡張および追加できます。- これらのリポジトリをコントローラーが使用するリポジトリにバインドするための依存性注入
IRepository<T>
。これにより、データの保存方法などを最小限の手間で切り替えることができます(ベストプラクティスだけでなく、これが発生する可能性が実際にあります)。これにはNinjectを使用しています。
私はこれまでこのようなことを最初から試みたことがないので、読んでいて、どこかで混乱していると思います。これまでのところ、コンストラクターに渡されるのインスタンスを含むIRepository<T>
によって実装されるインターフェイスがあります。このインターフェースには、Add、Update、Delete、およびさまざまなタイプのGet(IDによる単一、述語による単一、述語によるグループ、すべて)のメソッドがあります。(これまでのところ)このインターフェースに適合しない唯一のリポジトリーはUsersリポジトリーであり、ログインを許可するために追加されます(その実装はすべてのソルティング、ハッシュ、チェックなどを処理します)。BaseRepository<T>
DataContext
User Login(string username, string password)
私が読んだことからUnitOfWork
、すべてのリポジトリのインスタンスを含むクラスが必要になりました。この作業単位は、リポジトリとSaveChanges()メソッドを公開します。データを操作したいときは、作業単位をインスタンス化し、その上のリポジトリー(必要に応じてインスタンス化されます)にアクセスしてから保存します。何かが失敗した場合、データベースは最後に単一の保存に到達しないため、データベース内で何も変更されません。これはすべて問題ありません。私の問題は、私が見つけることができるすべての例が2つのことのいずれかを実行しているように見えることです。
- データコンテキストを作業単位に渡し、そこからさまざまなリポジトリを取得するものもあります。これは、私の作業単位にEntity-Framework固有
DbContext
(またはそれから継承されたクラス)を含めることによって、DIのポイントを否定します。 - Getメソッドを呼び出してリポジトリを要求する人もいます。これは、サービスロケーターパターンです。これは、アンチパターンではないにしても、少なくとも人気がありません。どちらにしても、ここでは避けたいと思います。
データソースのインターフェイスを作成し、それを作業単位にも注入する必要がありますか?説明するのに十分明確および/または完全なこれに関するドキュメントを見つけることができません。
編集
私はそれを複雑にしすぎていると思います。現在、リポジトリと作業単位を1つにまとめています。リポジトリは完全にジェネリックであるため、いくつかのジェネリックメソッド(Add、Remove、Update、およびいくつかの種類のGet)とSaveChangesメソッドが提供されます。これにより、ワーカークラスのインターフェイスが得られます。次に、そのインスタンスを提供するファクトリクラスを作成できます(これもインターフェイスされます)。このワーカーも実装しているIDisposable
場合は、スコープブロックで使用できます。これで、私のコントローラーは次のようなことができます。
using (var worker = DataAccess.BeginTransaction())
{
Product item = worker.Get<Product>(p => p.ID == prodName);
//stuff...
worker.SaveChanges();
}
の前に問題SaveChanges()
が発生した場合、スコープブロックを終了してワーカーが破棄されるときに、すべての変更が破棄されます。依存性注入を使用して、DataAccess
フィールドに具体的な実装を提供できます。これは、ベースコントローラーコンストラクターに渡されます。ビジネスロジックはすべてコントローラー内にあり、オブジェクトで機能するため、インターフェイスを実装している限りIQueryable
、プロバイダーオブジェクトを好きなものに切り替えることができます。EntityFrameworkに固有のものはどこにもありません。DataAccess
IRepository
それで、この実装について何か考えはありますか?これは正しい方向に進んでいますか?