🦨

appsettings.jsonとは何者なのか

2024/09/30に公開

appsettings.json とは主に ASP.NET CoreC# のプロジェクトで使われる設定ファイルだそうな。

私が今携わっている環境では appsettings.json 以外でも appsettings.Production.jsonappsettings.Development.json などが存在し、一体どれが『正』または『Primary』なのかこの際ちゃんと理解しようと思いまとめることにしました。
細かい表現や用語の誤用などあればご指摘ください。

「appsettings.json」について

appsettings.json はプロジェクト全体の基本設定

このファイルはプロジェクト全体基本となる設定が記載されたファイルとして作成されます。
「基本となる設定」に対し、環境に合わせた設定を上書きすることができます。

開発環境や本番環境に応じた appsettings.json

システムを動かす環境に応じて上書きすることができます。
上書きしたい内容を記載したファイル名を appsettings.Production.jsonappsettings.Development.json と命名することが多いそうです。
また総称して appsettings.{Environment}.json とも表現されています。
一般的には下記のように使用環境を示すファイル名を命名します。

ファイル名 使用環境
appsettings.json 基本設定(全環境共通)
appsettings.Development.json 開発環境用設定
appsettings.Staging.json ステージング環境用設定
appsettings.Production.json 本番環境用設定

またこれらのファイル名は任意での命名になるため、プロジェクトごとにファイル名や命名規則を変更できるようです。

上書きされる優先順位は?

公式ドキュメントから下記を引用。5から順番に呼び出され1の設定値が最終的に上書きされます。

  1. コマンドライン構成プロバイダーを使用するコマンドライン引数。
  2. 接頭辞なしの環境変数構成プロバイダーを使用した接頭辞なしの環境変数。
  3. Development 環境でアプリが実行される場合に使用されるユーザー シークレット。
  4. JSON 構成プロバイダーを使用する appsettings.{Environment}.json。 たとえば、appsettings.Production.json とappsettings.Development.json です。
  5. JSON 構成プロバイダーを使用する appsettings.json。

「appsettings.json」はどうやって呼び出されているのか

呼び出し時のソースコードを見てみよう

公式ドキュメントを読んでいるとGithubに飛ばされました。
ASP.NET Core フレームワークの Host.cs を見てみましょう。

Host.cs 該当部分
builder.ConfigureAppConfiguration((hostingContext, config) =>
{
    var env = hostingContext.HostingEnvironment;

    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
          .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

    if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
    {
        var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
        if (appAssembly != null)
        {
            config.AddUserSecrets(appAssembly, optional: true);
        }
    }

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
})

今回関連があるのはこの部分。

config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

"appsettings.json"と記載されているので、デフォルト値であることがわかります。
そしてreloadOnChange: trueの部分でファイルを有効化します。

「appsettings.{env.EnvironmentName}.json」はどうやって呼び出されているのか

{env.EnvironmentName} はどこで設定されているのか?

どこで ProductionDevelopment と設定されているのでしょうか?
IHostEnvironmentインターフェイスで定義されているようです。ではIHostEnvironmentインターフェイスが定義されているファイルを追跡します。

IHostEnvironment.cs
public interface IHostEnvironment
{
    string EnvironmentName { get; set; }
    string ApplicationName { get; set; }
    string ContentRootPath { get; set; }
    IFileProvider ContentRootFileProvider { get; set; }
}

ここで定義されていました。
また初期値を設定する場合は同ファイルに記載することが多いそうです。

システムは何を参照して動作環境を判断しているのか?

いくつか参照する箇所はあるようなのですが、主には ASPNETCORE_ENVIRONMENT 環境変数の値に基づいて設定をロードする仕組みのようです。
プロジェクトの Program.csWebHost.CreateDefaultBuilder(args) が使用されていおり、このメソッドが ASPNETCORE_ENVIRONMENT の値を引数にしています。

開発環境では launchsetting.json というファイルを参照されることが多いそうです。
下記は記入例

launchsetting.json
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  }

appsettings.Production.json はなぜか通る

実行環境をいろいろ調べてみましたが、Production を定義している箇所がみつかりません。
定義されていないのになぜ appsettings.Production.json はなぜロードされているのか?を追跡しました。結果 「デフォルトだと通る」 ということになるのですが、何をもってデフォルトとしているかが気になり、もう少し調べてみると下記の確認を行なっていることがわかりました。

  1. ASPNETCORE_ENVIRONMENT の設定を見に行く
  2. 設定があればその環境に対応した appsettings.{env.EnvironmentName}.json をロードする
  3. 設定がなければその環境を「Production」とみなし、appsettings.Production.jsonをロードする。

結論

Discussion