個人的には、ドメイン モデル オブジェクトのすべての CRUD 操作を処理し、インターフェイスを介してこのリポジトリを MVC コントローラーに渡す完全なリポジトリ クラスを作成するのが好きです。次に、コントローラーは、アプリケーション ロジックに応じて、リポジトリでさまざまなメソッドを実行します。
このアプローチには、主に次の 2 つの利点があると思います。
- リポジトリ内のデータ アクセス コードとコントローラー内のアプリケーション ロジック コードを明確に分離できます。したがって、リポジトリはデータ アクセスの完全な責任を負い、コントローラーはアプリケーション ロジックを維持します。
- これは、テスト用に構造化する効果的な方法です。インターフェイスを介してリポジトリをコントローラに渡すことで、RhinoMocks や Moq などのモック フレームワークを介してコントローラを完全にテストすることができます。効果的にテストすることが困難または不可能なデータ アクセス コードが、テストできない単一のクラスに集中しています。
たとえば、Product クラスで完全な CRUD 操作を行うコントローラーが必要だとします。以下に示すように、リポジトリ インターフェイスと実装を作成します。リポジトリの実装には、オブジェクト リレーショナル マッパー (ORM) またはデータ アクセス レイヤーのインスタンスが必要であることに注意してください。この例では、コンストラクターの ISession インターフェイスを介して nHibernate Session オブジェクトのインスタンスを渡します。
public interface IProductRepo
{
List<Product> GetProducts();
Product GetProduct(int Id);
void DeleteProduct(int Id);
void CreateProduct(Product product);
void UpdateProduct(Product product);
}
public class ProductRepo : IProductRepo
{
public ProductRepo(ISession session)
{
_session = session;
}
public Product GetProduct(int Id)
{
return _session<Product>().Get(Id);
}
//Implementation of other methods of IProductRepo
ISession _session;
}
このレポは、コンストラクター注入 (私のお気に入り) またはプロパティ注入を介してコントローラーに渡すことができます。したがって、コントローラーは次のようになります。
public class ProductController : ApiController
{
public ProductController(IProductRepo repo)
{
_repo = repo;
}
public List<Product> GetProducts()
{
//other code as needed
return _repo.GetProducts();
}
public Product GetProduct(int id)
{
//other code as needed
return _repo.GetProduct(id);
}
public void PostProduct(Product product)
{
_repo.CreateProduct(product);
//other code as needed
}
public void PutProduct(Product product)
{
_repo.UpdateProduct(product);
//other code as needed
}
public void DeleteProduct(int id)
{
_repo.DeleteProduct(id);
//other code as needed
}
}
Microsoft には、この Web API の基本的な例を説明する優れた記事があります。
編集:リポジトリパターン
マーティン・ファウラーの言葉で
リポジトリは、ドメイン レイヤーとデータ マッピング レイヤーの間を仲介し、メモリ内のドメイン オブジェクト コレクションのように機能します。
これは通常、nHibernate や Entity Framework などのオブジェクト リレーショナル マッパー (ORM) またはデータ アクセス レイヤーと組み合わせて使用されます。したがって、リポジトリは、実際に永続レイヤーへの書き込みと読み取りを行う ORM またはデータ アクセス クラスのインスタンスを取得します。リポジトリは、ORM/データ アクセス クラスに対するすべてのクエリと CRUD 操作をカプセル化するために使用されます。