miso_soup3 Blog

主に ASP.NET 関連について書いています。

帳票出力 In MVC 書き方

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();
}

おしまい

各責任者には、必要なものだけを渡して作業してもらいます。
帳票出力者には、必要最低限なViewModelを。

エクセル作成者にリポジトリインスタンスを渡したりすると、
何をしでかすかわかりません。

インターフェイスを定義しているので、テストも可能。

あと、Controller では、return View();の真似をして
return Excel("タイトル", byte[]); とかどうでしょう。

これから花見です(´∀`)