LoginSignup
9
4

More than 5 years have passed since last update.

【ASP.NET Core】JSONファイルから静的に型付けされた設定情報を簡単に得る方法

Posted at

はじめに

ASP.NET Core で JSON ファイルから設定情報を得てアプリに反映する手順です。
設定を文字列として読み込むのではなく、クラスにバインドし型付けして安全に扱いたいと思います。1

.NET Core SDK のバージョンは 2.1 で、 Visual Studio for Mac を使用しています。

$ dotnet --version
2.1.302

サンプルは以下の dotnet コマンド、もしくは Visual Srtuio で新規の Web API プロジェクトを作成したものです。

dotnet new webapi -o 'OptionsPattern'

参考にした URL
ASP.NET Core のオプション パターン
ASP.NET Core の AppSetting の構成方法

設定情報の記述とそれをバインドするクラスの作成

appsettings.jsonに自分の設定情報を追記します。

appsettings.json
  {
+   "option1": "value1_from_json",
+   "option2": -1,
+   "option3": "1637bb4c-fff4-48d9-af98-3e9d8f022ecc"
    "Logging": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AllowedHosts": "*"
  }

追記した設定情報をバインドするオプションクラスを作成します。
プロパティ名を JSON のキー名と同じにします。(大文字小文字は違っても大丈夫です。)
今回はstring型、int型、Guid型にバインドしてみます。

public class MyOptions {
  public string Option1 { get; set; }
  public int Option2 { get; set; }
  public Guid Option3 { get; set; }
}

設定情報のバインドと DI コンテナへの登録

Startup.csで設定情報をオプションクラスにバインドし、DI コンテナに登録します。

Startup.cs
public class Startup {
  public Startup(IConfiguration config) {
    // コンストラクタでコンフィグを初期化
    Configuration = config;
  }

  public IConfiguration Configuration { get; }

  public void ConfigureServices(IServiceCollection services) {
    // オプションを使用するためのサービスを追加します。
    services.AddOptions();
    // バインドするオプションクラスに対し、設定情報を登録します。
    services.Configure<MyOptions>(Configuration);

    // ※上記は services.AddMvc() より前で設定しなくても動きましたが、公式ドキュメント通り、前で設定しています。
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  }
  // 以下略
}

これだけで準備完了です。

設定情報の利用するには

設定情報をバインドしたオプションクラスを利用するには、クラスのコンストラクタ引数にIOptionsMonitor<TOptions>を持つとOptionsMonitor<TOptions>のインスタンスが DI されます。
オプションクラスはOptionsMonitor.CurrentValueプロパティから得られます。

今回はコントローラークラスを作成して設定情報を利用してみたいと思います。

OptionsController.cs
[Route("api/[controller]")]
[ApiController]
public class OptionsController: ControllerBase {

  // コンストラクタで OptionsMonitor<TOptions> が DI される
  public OptionsController(IOptionsMonitor<MyOptions> optionsMonitor) {
    // CurrentValueプロパティでオプションクラスのインスタンスが得られる
    options = optionsMonitor.CurrentValue;
  }

  // オプションクラスのインスタンスをフィールドに保持
  private readonly MyOptions options;

  // api/options
  [HttpGet]
  public IActionResult GetOptions() {
    // JSON で返してみる
    return Ok(options);
  }
}

デバッグしhttps://localhost:ポート番号/api/optionsにブラウザでアクセスします。
以下の画像の通り設定情報がクラスにバインドされているのが確認できます。
image.png
レスポンスが返えります。(※ Chrome 拡張の Json Viewer で見やすくしています。)
image.png

ネストした JSON の設定情報の読み込み

設定情報をセクションに分けて JSON に記述する場合、以下のように読み込みます。

appsettings.json
  {
    "option1": "value1_from_json",
    "option2": -1,
-   "option3": "1637bb4c-fff4-48d9-af98-3e9d8f022ecc"
+   "option3": "1637bb4c-fff4-48d9-af98-3e9d8f022ecc",
+   "subsection": {
+     "suboption1": "subvalue1_from_json",
+     "suboption2": 200,
+     "suboption3": "b2d0caf4-2aa0-4272-a175-50351282ab0f"
+   },
    "Logging": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AllowedHosts": "*"
  }
MySubOptions.cs
// バインドするクラスを用意
public class MySubOptions {
  public string SubOption1 { get; set; }
  public int SubOption2 { get; set; }
  public Guid SubOption3 { get; set; }
}
Startup.csから抜粋
  public void ConfigureServices(IServiceCollection services) {
    services.AddOptions();
    services.Configure<MyOptions>(Configuration);

+   // Configuration.GetSection("セクションのキー名") で読み込める
+   services.Configure<MySubOptions>(Configuration.GetSection("subsection"));

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  }
OptionsController.cs
  [Route("api/[controller]")]
  [ApiController]
  public class OptionsController: ControllerBase {
    private readonly MyOptions options;
    private readonly MySubOptions subOptions;

+   // セクションに分けずに記述した設定と同様に扱える
-   public OptionsController(IOptionsMonitor<MyOptions> optionsMonitor) {
+   public OptionsController(
+     IOptionsMonitor<MyOptions> optionsMonitor,
+     IOptionsMonitor<MySubOptions> subOptionsMonitor
+   ) {
      options = optionsMonitor.CurrentValue;
+     subOptions = subOptionsMonitor.CurrentValue;
    }

    [HttpGet]
    public IActionResult GetOptions() {
      return Ok(options);
    }

+   [HttpGet("sub")]
+   public IActionResult GetSubOptions() {
+     return Ok(subOptions);
+   }
  }

ネストした設定情報がバインドされているのが確認できます。
image.png
image.png

JSON ファイルはどこで読み込まれているのか?

ASP.NET Core で JSON ファイルを読み込むには、ConfigurationBuilderAddJsonFile拡張メソッドを呼び出します。
ただし、Program.csCreateDefaultBuilderメソッドで新しいWebHostBuilderを初期化すると、appsettings.jsonappsettings.{環境名}.jsonは自動で読み込まれるため、今回はそちらに設定を記述しました。

Program.csから抜粋
// ここで自動的に appsettings.json が読み込まれる
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();

サンプルの URL

GitHub の以下のリポジトリに今回のサンプルを置きました。
今回省略した名前空間のインポートなどを確認する場合、こちらで確認ください。
https://github.com/sano-suguru/OptionsPattern


  1. 従来の .NET Framework ではApp.configxmlファイルからSystem.Configuration名前空間のConfigurationSettings.AppSettings("キー名")を使って設定情報を読み込んでいました。戻り値は文字列です。 

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4