こんにちは、情報システム部の高野です。
だいぶ間が空いてしまいました。継続は中々難しいですね!
最近は、実プロジェクトにべったりなのでHoloLensの検証が一向に進みません。
この記事も実プロジェクトをやっていて気付いたことです。
とりあえず普通に設定を利用してみる
ASP.NET Core のオプションのパターン | Microsoft Docs
公式見れば分かります・・・が、一応書いておきます。
設定(appsettings.json)をアプリケーションで利用するには
まず設定を入れておくクラスを作ります。
public class ApiConfig { public string BaseUrl {get; set;} }
それよりも前にappsettings.jsonに設定の追加が必要ですね。
"HogeApi": { "BaseUrl": "http://example.com/api/" }
これを受けるのが上記のApiConfigクラスになります。
次にStartUpクラスのConfigureServicesメソッド内に下記を追加します。
services.Configure<ApiConfig>(Configuration.GetSection("HogeApi"));
最後に設定を利用したいクラスのコンストラクタの引数にIOptionsを追加します。
ApiConfig config;
public HomeController(IOptions<ApiConfig> option)
{
config = option.Value;
}
これでHomeController内でURLを取得することができるようになりました。
アプリケーション起動中に設定を変更し即時反映させる
IOptionsを利用すると設定は読み込めるのですが、アプリケーションを再起動しないと
設定の変更が反映されません。
再起動せずに設定を変更させる方法も公式に載っています。
ASP.NET Core のオプションのパターン | Microsoft Docs
ここに載っているそのまま
IOptionsをIOptionsSnapshotに変更すればいいだけです。
(以前は、別途設定が必要だったような気が・・・新しいテンプレートだと無くなってました)
アクションフィルターで設定を利用する
アクションフィルターで設定を用いて処理したいこともありますよね(きっとあるはず)
まずアクションフィルターを作ります。
こちらもコンストラクタを作成して引数でIOptionsを取るようにします。
(即時反映したいならIOptionsSnapshot)
sealed public class TestFilterAttribute : ActionFilterAttribute { ApiConfig config; public TestFilterAttribute(IOptions<ApiConfig> option) { config = option.Value; } }
利用するコントローラーに属性として付与します。
ただしこの場合は、ServiceFilterを利用する必要があります。
[ServiceFilter(typeof(TestFilterAttribute))] public class HomeController : Controller
StartUpクラスでインジェクションの設定をします。
services.AddScoped<TestFilterAttribute>();
これでアクションフィルターでも設定が利用できるようになったはずです。
上記にも書きましたがIOptionsSnapshotを使用して即時反映も可能です。
ミドルウェアでも設定が使いたい
ミドルウェアでも設定を使いたい時はあるでしょう(あるある)
ということでミドルウェアでもやってみる。
まずミドルウェアを作ります。
これも同じようにIOptionsをコンストラクタの引数で取ります。
public class TestMiddleware { readonly RequestDelegate next; ApiConfig config; public TestMiddleware(RequestDelegate next, IOptions<ApiConfig> options) { this.next = next; config = options.Value; } public async Task Invoke(HttpContext context) { await next.Invoke(context); } }
あとは、StartUpクラスでミドルウェアを登録するだけです。
app.UseMiddleware<TestMiddleware>();
これでミドルウェアでも設定が利用できるようになりました。
即時反映したいならIOptionsSnapshotを使います・・・とはいかないのです!
ミドルウェアのIOptionsをIOptionsSnapshotに変更すると下記のエラーが発生します。
An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.AspNetCore.Hosting.dll: 'Cannot resolve scoped service 'Microsoft.Extensions.Options.IOptionsSnapshot`1[OptionsStudy.ApiConfig]' from root provider.'
どうやらScopedで作成したServiceはミドルウェアでは利用できないようです。
IOptionsSnapshotはAddScopedメソッドで登録されています。
IOptionsはAddSingletonメソッドでした。
それでは、ミドルウェアではIOptionsSnapshotは利用できず即時反映はできないのか?
ところができるのです。
コンストラクタの引数を消してInvokeメソッドの方に移すだけでした。
(これが分からず苦労した)
public async Task Invoke(HttpContext context, IOptionsSnapshot<ApiConfig> options) { var conf = options.Value; // ・・・ await next.Invoke(context); }
まとめ
IOptionsSnapshotをインジェクションすればアプリケーションを再起動しないでも
設定の変更を反映することができる。
でもミドルウェアは、コンストラクタの引数ではなくInvokeメソッドの引数なので注意!
弊社ではエンジニアを募集しています。
興味がある方は下記からエントリお願いします。
athome-inc.jp