.NET5でappsettingsをDIし、独自クラスにバインドする方法

f:id:tanabebe:20210329223028p:plain

DB接続文字列にappsettings.jsonファイルを使用しようと思った時に、すっかり方法を忘れていたので、今回は.NET5でJSONファイル構成プロバイダーを扱う方法について書きます。何パターンか方法はありますが、クラスにバインドする方法で進めていきます。また、作成したプログラムはGitHubにあげています。

github.com

1. 環境

❯❯❯ dotnet --version
5.0.103

Web APIのテンプレート(dotnet new webapi -n Apiなど)でプロジェクトが作成されている前提で進めます。

2. JSON構成ファイルを修正する

appsettings.Deplopment.jsonファイル内に下記のSettings以降を追加します。私はConnectionStringsに自身のAzure SQL Databaseの接続文字列を設定しました。環境毎に読み込み先のjsonファイルを変更する方法には触れませんので、詳細はこちらをご覧ください。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "Settings": {
    "Database": {
      "ConnectionStrings": "Your connection string"
    }
  }
}

3. 読み込んだJSON構成ファイルをバインドするクラスを作成

簡素ですが、Databaseというクラスを作成しています。

// DapperTest/Api/Database.cs
public class Database
{
    public string ConnectionStrings { get; set; }
}

4. サービスコンテナに処理を追加する

Startupクラスが呼ばれるタイミングで構成ファイルを読み取り、前述で作成したDatabaseクラスにバインドするように処理を追加します。
JSON構成ファイル内のKeyバインドするクラスのプロパティが一致しない場合 、値は取得出来ないので注意。クラス名は大丈夫です。

// DapperTest/Api/Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<Database>(Configuration.GetSection("Settings:Database")); // 追加
    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "Api", Version = "v1" });
    });
}

5. 対象クラスのコンストラクタでインジェクションする

ここではDapperTestControllerというクラスを作成しています。コンストラクタでIOptionsMonitorを受け取り、_optionsに設定しました。これで値を取り出す事が出来ます。ここではSqlConnectionで使用しています。これにて完了。

public class DapperTestController : BaseController
{
    private readonly Database _options;

    public DapperTestController(IOptionsMonitor<Database> options)
    {
        _options = options.CurrentValue;
    }

    [HttpGet]
    public async Task<ActionResult<List<Customer>>> GetSample()
    {
        using (var db = new SqlConnection(_options.ConnectionStrings))
        {
            var results = await db.QueryAsync<Customer>("Select * From Customers");
            return results.ToList();
        }
    }
}

6. まとめ

今回はDapperとの接続方法を試していた際に少しハマってしまった、JSONファイル構成プロバイダーを扱う方法について書きました。
そもそもですが、DIは知ればこそ強力ですね。newでインスタンス化するよりスマートです。ただし、隠蔽されている感じが強くあるので、DIを理解していない場合は命取りにはなりそう。
前述のコンスタラクタでIOptionsMonitorを受け取っていますが、Microsoft Docsを見る限り、これには3種類のオプションがあります。今回は常に最新のオプション値を取得するとあったIOptionsMonitorを使用しました。IOptionsSnapshotも試したところ同じような挙動はするのですが、使い所がパッと思い浮かばなかった、というのが正直な感想です。

7. 参考

docs.microsoft.com

docs.microsoft.com

blog.ecbeing.tech

www.amazon.co.jp