はじめに
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
に自分の設定情報を追記します。
{
+ "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 コンテナに登録します。
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
プロパティから得られます。
今回はコントローラークラスを作成して設定情報を利用してみたいと思います。
[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
にブラウザでアクセスします。
以下の画像の通り設定情報がクラスにバインドされているのが確認できます。
レスポンスが返えります。(※ Chrome 拡張の Json Viewer で見やすくしています。)
ネストした JSON の設定情報の読み込み
設定情報をセクションに分けて 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": "*"
}
// バインドするクラスを用意
public class MySubOptions {
public string SubOption1 { get; set; }
public int SubOption2 { get; set; }
public Guid SubOption3 { get; set; }
}
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);
}
[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);
+ }
}
JSON ファイルはどこで読み込まれているのか?
ASP.NET Core で JSON ファイルを読み込むには、ConfigurationBuilder
のAddJsonFile
拡張メソッドを呼び出します。
ただし、Program.cs
のCreateDefaultBuilder
メソッドで新しいWebHostBuilder
を初期化すると、appsettings.json
とappsettings.{環境名}.json
は自動で読み込まれるため、今回はそちらに設定を記述しました。
// ここで自動的に appsettings.json が読み込まれる
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();
サンプルの URL
GitHub の以下のリポジトリに今回のサンプルを置きました。
今回省略した名前空間のインポートなどを確認する場合、こちらで確認ください。
https://github.com/sano-suguru/OptionsPattern
-
従来の .NET Framework では
App.config
xmlファイルからSystem.Configuration
名前空間のConfigurationSettings.AppSettings("キー名")
を使って設定情報を読み込んでいました。戻り値は文字列です。 ↩