- 投稿日:2020-09-17T23:35:08+09:00
ASP.NET Core における Razor(*.cshtml) ファイルの実行時コンパイル
ASP.NET Core での Razor ファイルのコンパイル
ASP.NET Core では、Web ページ(.csthml) の実行時コンパイルがデフォルトでは有効になっていません。
Razor は、HTML にインラインで、C# のコードを記述できて、非常に強力なのですが、レイアウトの調整や JavaScript のデバッグ時に、cshtml を編集するたびに実行するのでは、非常に手間がかかります。ASP.NET Core では、Visual Studio のデバッグ実行状態で、.cshtml を編集して保存、ブラウザで該当ページをリロードして、変更内容を反映させるためには、コードに手を入れる必要があります。
ここでは、開発環境での実行時のみ、.cshtml の実行時コンパイルを有効にする手順を説明します。
補足ですが、ここでの開発環境での実行時とは、ASPNETCORE_ENVIRONMENT 環境変数が、Development に設定されている場合を指しています。Visual Studio では、ASP.NET Core プロジェクトの [プロパティ] - [デバッグ] から、起動プロファイル毎に、ASPNETCORE_ENVIRONMENT の値が設定できます。デフォルトは、Development に設定されています。
起動時にどのプロファイルを使用するかは、デバッグ実行ボタンから選択できます。
RazorRuntimeCompilation パッケージの追加
ASP.NET Core プロジェクトに、RazorRuntimeCompilation を追加します。
[ソリューション エクスプローラー] - [<対象プロジェクト>] 選択し、右クリック メニューから、[NuGet パッケージの管理] を選択、[参照] を選択し、"RazorRuntimeCompilation" を検索し、"Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" パッケージをインストールします。
Starup.cs の編集
Starup.cs を編集していきます。ConfigureServices メソッド内の "services.AddRazorPages()" を "services.AddRazorPages().AddRazorRuntimeCompilation();" とすれば、実行時コンパイルが有効になるのですが、今回は、開発環境でのみ実行時コンパイルが有効になるようにします。
Startup クラスのインスタンス生成時に、IWebHostEnvironment のインスタンスを保存するために、コンストラクタに引数を追加します。依存性の注入なので、既存のコンストラクタを編集して、引数を追加してください。
Startup.cs//IWebHostEnvironment のインスタンス保存用 private IWebHostEnvironment _webHostEnvironment; public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; //IWebHostEnvironment のインスタンスを保存 this._webHostEnvironment = env; }次に、ConfigureServices メソッドを編集します。保存しておいた IWebHostEnvironment のインスタンスを参照し、デバッグ時のみ実行時コンパイルが有効になるように、AddRazorRuntimeCompilation をコールします。
Startup.cspublic void ConfigureServices(IServiceCollection services) { var mvcBuilder = services.AddRazorPages(); if (this._webHostEnvironment.IsDevelopment()) { //実行時コンパイルの有効化 mvcBuilder.AddRazorRuntimeCompilation(); }以上で、開発環境での実行時のみ .cshtml ファイルの実行時コンパイルが有効となります。
Razor ファイルの実行時コンパイルは、開発時において非常に利便性が高いので、是非とも活用ください。
参考サイト
- 投稿日:2020-09-17T22:33:09+09:00
ループ中にリストの要素を削除する場合の注意点
リストをループで回している中で、そのリストの要素を削除する場合は、ループを逆順で回しましょう。
NGfor (int i = 0; i < enemyList.Count; i++) { if (!enemyList[i].IsAlive) { enemyList.RemoveAt(i); } }OKfor (int i = enemyList.Count - 1; i >= 0; i--) { if (!enemyList[i].IsAlive) { enemyList.RemoveAt(i); } }なぜ逆順にしなければならないのか?を示したものが以下の図になります。NG側では、要素
C
を削除した際に後ろにある要素が一つ前に詰められる影響で、要素D
が正しく処理されない問題が発生しています。ちなみに、リストの要素を削除したいけどループ中に処理する必要はない時には
RemoveAll
が便利です。enemyList.RemoveAll(enemy => !enemy.IsAlive);参考リンク