ASP.NET Core と launchSettings.json と appSettings.json

# はじめに

Visual Studio で、ASP.NET Core のテンプレートを使いコードを生成すると、launchSettings.json と appSettings.json といった構成情報を管理するファイルが生成されます。
これらを活用すると、環境に応じて処理を分岐して記述すること、参照する構成情報を分けて管理できるようになるので、使用用途と使用方法をまとめてみました。

# launchSettings.json

launchSettings.json は、端的に言うと起動プロファイルです。デバッガーからプログラムを起動する際の各種設定をプロファイル単位で定義できます。どのプロファイルを適用して起動するかは、デバッガー起動時に指定します。

以下は、ASP.NET Core の launchSettings.json の例です。"IIS Express",  "LaunchSettingsDemo", Profile001" といったプロファイルを定義しています。

```json:launchSettings.json
{
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "LaunchSettingsDemo": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    },
    "Profile001": {
      "commandName": "IISExpress",
      "launchBrowser": true
    }
  }
}
```
各プロファイル毎の commandName では、起動する Web サーバーを指定します。

- IISExpress - IIS Express を起動します。(Visual Studio 2019 ではデフォルトで設定されます。)
- IIS - IIS を起動します。
- Project - Kestrel Web サーバーを起動します。

Kestrel Web Server は、ASP.NET Core 用のクロス プラットフォーム対応 Web サーバーです。
以下のサイトに説明があります。Linux, MacOS 環境でも利用できます。

- [Kestrel web server implementation in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel)


"launchBrowser" は、ブール値を指定し、デバッガー起動時に、ブラウザを起動するかをブール値で指定します。
"environmentVariables" が重要で、環境変数と値を設定できます。ここで、"ASPNETCORE_ENVIRONMENT" の値を設定することで、実行環境の定義を行います。
"ASPNETCORE_ENVIRONMENT" に設定する値は、任意の値を設定可能ですが、以下の値が定義されています。

- Development - 開発環境 
- Staging - ステージング(本番環境へ展開前のリハーサル)環境
- Production - 本番環境

これらの値を定義しないと、Staging として扱われます。

# 起動プロファイルの選択

どのプロファイルから起動するかは、Visual Studio の場合は、デバッグ実行ボタンから選択できます。
![起動プロファイルの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172205/d6e0051d-a8e1-f2fa-dff6-948390b125d0.png)

.NET Core CLI の場合は、run の --launch-profile オプションで、プロファイル名を指定します。

```shell:dotnet

dotnet run --launch-profile <プロファイル名>
```

# ASPNETCORE_ENVIRONMENT の参照

ASPNETCORE_ENVIRONMENT 環境変数の設定値は、IHostingEnvironment.EnvironmentName プロパティから参照できます。また、IHostingEnvironment の拡張メソッド、IsDevelopment, IsStaging, IsProduction, IsEnvironment を使って、現在の環境に応じた処理を記述できます。

ASP.NET Core のコントローラー、PageModel からこれらを参照するには、依存性の注入がされた IWebHostEnvironment のインスタンスをコンストラクター経由で取得、参照を保存し、利用します。
この例では書いてないですが、ASPNETCORE_ENVIRONMENT に任意の名前を定義した場合は、IsEnvironment(string environmentName) で評価することもできます。

```Index.cshtml.cs
public class IndexModel : PageModel
{
    public string Message;

    private readonly IWebHostEnvironment _env;
    private readonly ILogger<IndexModel> _logger;

    public IndexModel(IWebHostEnvironment env, ILogger<IndexModel> logger)
    {
        this._env = env;
        this._logger = logger;
    }

    public void OnGet()
    {
        if (this._env.IsDevelopment())
        {
            this.Message = "I'm Development.";
        }
        else if (this._env.IsStaging())
        {
            this.Message = "I'm Staging.";
        }
        else if (this._env.IsProduction())
        {
            this.Message = "I'm Production.";
        }
        else
        {
            this.Message = "I'm Others.";
        }
    }
}

```

Razor(*.cshtml) での場合でも、もちろん依存性の注入と拡張メソッドで同様のコードを記述できます。

```csharp:Index.csthml

@page
@using Microsoft.Extensions.Hosting
@using Microsoft.AspNetCore.Hosting
@inject IWebHostEnvironment HostEnvironment
@{
    string Message;

    if (HostEnvironment.IsDevelopment())
    {
        Message = "I'm Development.";
    }
    else if (HostEnvironment.IsStaging())
    {
        Message = "I'm Staging.";
    }
    else if (HostEnvironment.IsProduction())
    {
        Message = "I'm Production.";
    }
    else
    {
        Message = "I'm Others.";
    }
}

```
Razor(*.cshtml) では、environment 要素により環境に応じたレンダリングの分岐ができます。
以下の例では、開発環境の場合には、jquery.js を参照し、それ以外の場合は、jquery.min.js を参照しています。

```html:_Layout.cshtml

<environment include="Development">
    <script src="~/lib/jquery/dist/jquery.js"></script>
</environment>
<environment exclude="Development">
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
</environment>
```

# appSettings.json

appSettings.json は、アプリの構成情報を管理できます。定義したキーと値の取得方法は以下で説明してます。

- [ASP.NET Core 3.1 MVC における構成ファイル appsettings.json からの値取得](https://qiita.com/hiromasa-masuda/items/6916fc60c34cdca965a0)

ポイントは、ASPNETCORE_ENVIRONMENT 環境変数によって、参照する appSettings.json を変えることができます。
ファイル名を appSettings.%ASPNETCORE_ENVIRONMENT%.json といった書式にすることで、参照先の構成情報を変えることことができます。

- appSettings.json
- appSettings.Development.json
- appSettings.Staging.json
- appSettings.Production.json

対応する環境変数が含まれたファイルがない場合は、appSettings.json が参照されます。

# まとめ

launchSettings.json は、起動プロファイルの定義。デバッガー起動時にどのプロファイルを使用するか、指定できます。起動プロファイルの主な役割は、ASPNETCORE_ENVIRONMENT 環境変数の定義。
appSettings.json は、アプリの構成情報の定義。ASPNETCORE_ENVIRONMENT の定義により、参照先のファイルを変更できます。

launchSettings.json、appSettings.json を使用しなくても、すべてを環境変数で管理できますが、json ベースで構成情報を設計すると、階層的に構成情報を定義でき、管理がしやすくなると考えます。

# 参考サイト

- [Use multiple environments in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments)