MVCにて、ビューにわたすものを、ModelではなくViewModelにする、という書き方がありますが、
帳票出力の場合も、同じように考えると、綺麗に書けました。
エクセル出力を例にして、その方法を記載します。
全体像
http://aspnetdesignpatterns.codeplex.com/
恐縮ながら…ここのアーキテクチャの図を利用しました。
Service層の下に、帳票出力のプロジェクト、ExcelCreatorを追加します。
Controller
Controllerは、Serviceにリクエストし、受け取ったものを返すだけ。
public ActionResult AnimalListExcel(BukkenSingleProcessFormModel model) { var request = new GetAnimalListExcelRequest() { Type = AnimalType.Reptiles, }; var response = _animalService.GetAnimalsListExcel(request); return Excel(response.Content, response.Title); }
Service
Serviceは、エクセル作成者にこのViewModelで作って、と依頼します。
単体テストでは、エクセル作成者に渡したものを検証したり、
エクセル作成者から受け取ったものを返しているかどうか?などをテストとして書きます。
public AnimalService() { public AnimalService( IAnimalRepository animalRepository, IAnimalExcelCreator animalExcelCreator) { _animalRepository = animalRepository; _animalExcelCreator = animalExcelCreator; } public GetAnimalListExcelResponse GetAnimalsListExcel(GetAnimalListExcelRequest request) { //モデルを取得 var animals = _animalRepository.GetAllBy(request.Type); //エクセルを作成するためのものをViewModelとして渡す var material = new AnimalsListMaterial() { Animals = animals.ConvertToViews(); }; //エクセル作成してもらう byte[] contents = _animalExcelCreator.Create(material); var response = new GetAnimalListExcelResponse() { Title = "どうぶつたち", Contents = contents }; return response; } }
エクセル作成者
えぬぽい!
public byte[] Create(BukkenSingleProcessData data) { _data = data; //ヘッダー作成 CreateDateHeader(); //動物データ作成 CreateBody(); return _book.ToBytes(); }