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 に設定されています。
![ASPNETCORE_ENVIRONMENT](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/cfd8396b-556b-2820-6d24-1f4b5825a4fe.png)

起動時にどのプロファイルを使用するかは、デバッグ実行ボタンから選択できます。
![Debug Button](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/662994ef-b9d8-a5a4-65de-26afb8c5651b.png)


# RazorRuntimeCompilation パッケージの追加

ASP.NET Core プロジェクトに、RazorRuntimeCompilation を追加します。

[ソリューション エクスプローラー] - [<対象プロジェクト>] 選択し、右クリック メニューから、[NuGet パッケージの管理] を選択、[参照] を選択し、"RazorRuntimeCompilation" を検索し、"Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" パッケージをインストールします。
![RazorRuntimeCompilation](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/db8e4624-ee2f-7300-5247-1b26c1317694.png)

:::note info
2023/03 追記
以下のようなメッセージが表示される場合は、.NET のバージョンと RazorRuntimeCompilation のバージョンの互換性がありません。.NET のバージョンと同系の RazorRuntimeCompilation のバージョンを選択してください。.NET 6.0 の場合は、RazorRuntimeCompilation 6.0.14 で動作します。

パッケージ Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 7.0.3 は net6.0 (.NETCoreApp,Version=v6.0) と互換性がありません。 パッケージ Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 7.0.3 がサポートするもの: net7.0 (.NETCoreApp,Version=v7.0)	
:::

# Starup.cs の編集

Starup.cs を編集していきます。ConfigureServices メソッド内の "services.AddRazorPages()" を "services.AddRazorPages().AddRazorRuntimeCompilation();" とすれば、実行時コンパイルが有効になるのですが、今回は、開発環境でのみ実行時コンパイルが有効になるようにします。

Startup クラスのインスタンス生成時に、IWebHostEnvironment　のインスタンスを保存するために、コンストラクタに引数を追加します。依存性の注入なので、既存のコンストラクタを編集して、引数を追加してください。

```csharp:Startup.cs

//IWebHostEnvironment のインスタンス保存用
private IWebHostEnvironment _webHostEnvironment;

public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
   Configuration = configuration;
   //IWebHostEnvironment のインスタンスを保存
   this._webHostEnvironment = env;
}
```

次に、ConfigureServices メソッドを編集します。保存しておいた IWebHostEnvironment のインスタンスを参照し、デバッグ時のみ実行時コンパイルが有効になるように、AddRazorRuntimeCompilation をコールします。

```csharp:Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    var mvcBuilder = services.AddRazorPages();

    if (this._webHostEnvironment.IsDevelopment())
    {
        //実行時コンパイルの有効化
        mvcBuilder.AddRazorRuntimeCompilation();
    }
```
以上で、開発環境での実行時のみ .cshtml ファイルの実行時コンパイルが有効となります。

:::note info
2023/03 追記
現行のバージョンだと Program.cs で以下のように書けます。

```csharp:Program.cs
public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    var mvcBuilder = builder.Services.AddRazorPages();

    if (builder.Environment.IsDevelopment())
    {
        mvcBuilder.AddRazorRuntimeCompilation();
    }
...
}
```
:::


Razor ファイルの実行時コンパイルは、開発時において非常に利便性が高いので、是非とも活用ください。

# 参考サイト
- [Razor file compilation in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-compilation)
https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-compilation)