ASP.NET CoreでRazorの裏側が少し変わった

ASP.NET MVCやWebPagesで大活躍のRazorビューエンジン。ASP.NETの一員ということで、vNextのオープンソース化と共にGitHubでソースコードが公開されています

この記事では、Razorのクラスを自分で使う場合にわかる変化について紹介します。

Legacyという今までのRazorを使ったプロジェクトと、NewというASP.NET CoreからのRazorを使ったプロジェクトを用意し、比較します。ソースコード等はこちらから

名前空間の変更

NuGetからライブラリを用意する場合のRazorの識別名は、今も変わらずMicrosoft.AspNet.Razorです。
しかし、名前空間を見てみると、以前はSystem.Web.Razor配下であるのに対し、CoreではMicrosoft.AspNet.Razorとなっています。

GeneratedClassContextクラスのコンストラクタの変化

このクラスは、RazorEngineHostを使ってコード生成について設定する際、GeneratedClassContextプロパティ(名前が同じ)に指定するためのものです。

従来の場合、使用するメソッド名を指定する際は3つの名前だけを引数に取るオーバーロードがありました。

			var host = new RazorEngineHost(language)
			{
				DefaultBaseClass = nameof(Legacy) + "." + nameof(LegacyTemplateBase),
				DefaultClassName = "Generated",
				DefaultNamespace = "RazorTemplate",
				// 生成されるメソッド名の指定(これはデフォルトと同じものを指定している)
				GeneratedClassContext = new GeneratedClassContext(
					nameof(LegacyTemplateBase.Execute),
					nameof(LegacyTemplateBase.Write),
					nameof(LegacyTemplateBase.WriteLiteral)
				)
			};

ASP.NET Coreでは、これをメソッド名を3つ指定する際にはGeneratedTagHelperContextクラスのインスタンスが新たに必要になりました。

			var host = new RazorEngineHost(language)
			{
				DefaultBaseClass = nameof(New) + "." + nameof(NewTemplateBase),
				DefaultClassName = "Generated",
				DefaultNamespace = "RazorTemplate",
				// 生成されるメソッド名の指定(これはデフォルトと同じものを指定している)
				GeneratedClassContext = new GeneratedClassContext(
					nameof(NewTemplateBase.ExecuteAsync),
					nameof(NewTemplateBase.Write),
					nameof(NewTemplateBase.WriteLiteral),
					new GeneratedTagHelperContext { }
				)
			};

プロパティを見る限りでは、タグの生成に関する設定をするためのもののようです。なぜこうしたのかは不明。

Razorが生成するオブジェクトがガラリと変わった

従来の場合、RazorTemplateEngine#GenerateCodeメソッドは、その名前からのイメージと違い、コードのDOMを生成していました。そして、そのDOMを使って文字列を出力するプログラムへとコンパイル、実行していました。

				// コードDOM生成
				var generatorResults = engine.GenerateCode(reader);
				System.CodeDom.CodeCompileUnit unit = generatorResults.GeneratedCode;

ASP.NET Coreでは、ソースコードそのものを文字列型で出力するようになりました。

				//ソースコード生成
				var generatorResults = engine.GenerateCode(reader);
				string source = generatorResults.GeneratedCode;

Razorで生成されるメソッドが非同期に対応

従来は、生成されるクラス内でHTMLなどを出力するメソッドはvoid型のExecuteでした。

		public abstract void Execute();

		public string Generate()
		{
			Execute();
			return builder.ToString();
		}

ASP.NET Coreでは、Task型のExecuteAsyncになり、async/awaitで非同期処理ができるようになりました。

		public abstract Task ExecuteAsync();

		public async Task<string> GenerateAsync()
		{
			await ExecuteAsync();
			return builder.ToString();
		}

おわりに

ASP.NET MVCからcshtmlをRazorで変換するという、いつもの処理をする際には、今までとほとんど変わらない使用法になります。もしRazorを単体で使う場合には、今までの資料が役に立たない可能性があります。
そうした場合に参考になれば幸いです。

参考記事

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です