14

私のASP.NET MVCアプリケーションでは、データアクセスのために作業単位とリポジトリパターンを使用しています。ビジネスモデルをビューモデルに変換する場所は?

作業単位クラスとその内部で定義されたリポジトリを使用して、コントローラ内の関連エンティティのセットを取得しています。私の初心者の知識では、ビジネスモデルをフェッチしてビューモデルに変換する2つの方法を考えることができます。

  • リポジトリは、モデルを表示するためにマップされた、または
  • リポジトリ自体がモデルを表示するために、ビジネスモデルを変換し、それをコントローラに返されるよりも、このモデルをコントローラするビジネスモデルを返します。

現在、私は最初のアプローチを使用していますが、コントローラコードは、多くのプロパティを持つビューモデルでは見栄えが悪く、長く見え始めました。

一方、私のリポジトリはUserRepository(たとえば)と呼ばれているので、単一のビューのみに便利なモデルではなく、ビジネスモデルを直接返す必要があると考えています。

大きなプロジェクトでは、これらのうちどれが良いと思いますか?別の方法がありますか?

ありがとうございました。

+1

この質問に対する私の[回答] [1]は、これがよりうまくいく方法を説明する必要があります。 [1]:http://stackoverflow.com/questions/3747383/best-practices-to-partition-model-code-to-logical-parts-in-mvc-which-is-the- bes/3747474#3747474 –

答えて

20

リポジトリは、モデルを表示、ドメインモデルを返す必要がありません。モデルとビューモデルの間のマッピングに関しては、個人的にはAutoMapperを使用しているので、別のマッピングレイヤーがありますが、このレイヤーはコントローラから呼び出されます。

反復マッピング・ロジックを回避するために、カスタムアクションフィルターを短縮することができ、もちろんの
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カスタムここ

は、典型的なGETコントローラのアクションは次のようになります方法ですアクションフィルタはOnActionExecutedイベントにサブスクライブし、ビュー結果に渡されたモデルをインターセプトし、マッピングレイヤー(私の場合はAutoMapper)を呼び出してビューモデルに変換し、ビューに代入します。もちろん、ビューはビュー・モデルに強く型付けされています。

+0

tyとても。 Automapperについて知らなかったそれは私の問題で必要なものです。 –

+0

カスタムアクションフィルタのアプローチはテスト可能ですか?これが単体テストの中から呼び出された場合、自動マッパはどのように機能しますか? –

+1

@ JoshuaBarker、単体テストの全ポイントは、機能を単独でテストすることです。では、ここで孤立してテストしたいのは何ですか?オートマップ属性?グレート、そのための単体テストを書いてください。または、ドメインモデルをビューに渡しているコントローラアクション?グレート、そのための単体テストを書いてください。または、あなたのコントローラーアクションがAutoMap属性で装飾されているという事実?グレート、そのための単体テストを書いてください。これまでのところ、3つの単体テストに、コントローラの動作が期待どおりに動作することを確認するために必要なものがすべて書かれています。 –

2

あなたのリポジトリはビジネスモデルを返すべきだと思います。

次に、Automapperのようなツールを使用してプロパティを自動的にviewmodelにマップし、手動マッピングコードを取り除くことができます。このアプローチは、ビジネスエンティティのすべてのプロパティまたはそのcomples構造をビューに公開したくない場合に非常に便利です。

postは、マニュアルマッピングの呼び出し(並べ替え)を取り除くことができ、ビューモデルなどを使用する方法の良い例を提供しています(私の意見では) - または少なくとも何らかの種類インスピレーションのポストから

抜粋(属性がViewModelにする変換フォームbusionessモデルを行います):

[AutoMap(typeof(Product), typeof(ShowProduct))] 
public ActionResult Details(int id) 
{ 
    var product = _productRepository.GetById(id); 

    return View(product); 
} 
+0

非常に多く。ダーリンの答えは少し詳細であるので、私は彼の答えを受け入れています。あなたが気にしないことを願っています。 –

+0

ありがとう、それは素敵です。情報をありがとうございます - 私はダーリンの答えは同じ内容を持っているが、それをより良く提示していることに同意します(したがってより良い答えです)。 Viewmodelsなどの面白い情報があるかもしれないので、まだリンクを読むことをお勧めします。 –

+0

ありがとうございました。私は現時点でそれを読んでいます:) –

関連する問題