リポジトリは、ビューモデルではなく、ドメインモデルを返す必要があります。モデルとビューモデル間のマッピングに関しては、個人的にAutoMapperを使用しているため、別のマッピングレイヤーがありますが、このレイヤーはコントローラーから呼び出されます。
典型的なGETコントローラーアクションは次のようになります。
public ActionResult Foo(int id)
{
// the controller queries the repository to retrieve a domain model
Bar domainModel = Repository.Get(id);
// The controller converts the domain model to a view model
// In this example I use AutoMapper, so the controller actually delegates
// this mapping to AutoMapper but if you don't have a separate mapping layer
// you could do the mapping here as well.
BarViewModel viewModel = Mapper.Map<Bar, BarViewModel>(domainModel);
// The controller passes a view model to the view
return View(viewModel);
}
もちろん、繰り返しのマッピングロジックを回避するために、カスタムアクションフィルターを使用して短縮することもできます。
[AutoMap(typeof(Bar), typeof(BarViewModel))]
public ActionResult Foo(int id)
{
Bar domainModel = Repository.Get(id);
return View(domainModel);
}
AutoMapカスタムアクションフィルターはOnActionExecutedイベントをサブスクライブし、ビュー結果に渡されたモデルをインターセプトし、マッピングレイヤー(私の場合はAutoMapper)を呼び出してビューモデルに変換し、ビューの代わりに使用します。もちろん、ビューはビューモデルに強く型付けされています。