AutoMapper + ViewModel In MVC その1
MVCで書くときのポイント、
- その1.適切なViewModelを作る
- その2.AutoMapperのテスト、確認
この2点のうち、その1を書きたいと思います。
その1.適切なViewModelを作る
MVCでゴリゴリ書いていると、適切なViewModelを作ることが
大事だなと感じます。
このあたりの設計パターンの説明はできませんが、
ViewModelを作らないと、どんな困ったことがおきるか?
具体例を発見したので記載します。
例えばイベント管理アプリ。
イベントは、タイトルと、予定日(Null許可)の2つの項目をもっています。
このModelとViewModelを使って、以下の用に「イベント一覧」を作成したとします。
「イベント一覧」の View
<h2>イベント一覧</h2> <table> <tr> <td>タイトル</td> <td>予定日</td> </tr> <tr> @foreach (var projectEvent in Model.ProjectEvents) { <td>@projectEvent.Title</td> <td> @if(projectEvent.PlanDate.HasValue) { @projectEvent.PlanDate.Value } </td> } </tr> </table>
で、次。
「イベント一覧」の他に、「今週のイベント一覧」を作成するときはどうするか、です。
先程のViewModelであるProjectEventViewを使いまわすと、
以下のようになってしまいます。
「今週のイベント一覧」の View
<h2>今週のイベント一覧</h2> <table> <tr> <td>日付</td> <td>タイトル</td> </tr> <tr> @foreach (var projectEvent in Model.ProjectEvents) { <td> @if (projectEvent.PlanDate.HasValue) { @projectEvent.PlanDate.Value } </td> <td>@projectEvent.Title</td> } </tr> </table>
「イベント一覧」のコードとあまり差がないんですが・・・。
「今週のイベント一覧」なのに、なんで予定日がNullかもしれないの?if文いらなくない?
と開発者が疑問に思います。
余計なコードは書きたくないですし、バグも発生しやすくなります。
解決策は、「今週のイベント一覧」にあうViewModelを別に作ることです。
PlanDateが、DateTime?ではなく、DateTime型になっています。
もっと突き詰めると、
とかも良いと思います。
おしまい
以上のように、ページの概念に基づいた適切なViewModelを作成することで、
自然なコードがかけるようになります。
Model 1コに対し、ViewModelはいくつでも作ってよいと思います。
ModelからViewModelを作成する際には、AutoMapperを使っています。
次はその辺りを書きます。(書きました。→その2.AutoMapperのテスト、確認
おまけ FormModel
Controller側では、ViewModelを作成・組み立てたりしない方が良いです。
また、ViewModelとは別に、FormModelを
画面:FormModel = 1 : 1 で作成するといろいろ便利でした。
(Razor側で変更があった時に、余計な修正を加えなくて済みません。)
(FormModelとは私がそう呼んでいるだけで、ModelとかContainerと呼称するサンプルもありました。)
public ActionResult List() { var response = _service.GetAllProjectEvent(); IEnumerable<ProjectEventView> events = response.ProjectEvents; var model = new ProjectEventListFormModel(); model.ProjectEvents = events; return View(model); }