ASP.NET Coreノート(4)-オプションモード
4849 ワード
オプションインタフェース
ASP.NET Coreオプションモードでよく使われるインタフェースは
IOptionsは、構成変更時に変更オプションの値に対応できず、適用のみを再起動できます.IOptionsSnapshotとIOptionsMonitorはこの能力を持っている.
オプションはサービスとして使用できます.次のコードはオプションの使用シーンをシミュレートし、OrderServiceOptionsはOrderServiceのオプションとして注入され、OrderServiceはコントローラに注入されます.
public interface IOrderService
{
int ShowMaxOrderCount();
}
public class OrderService : IOrderService
{
IOptionsSnapshot _options;
public OrderService(IOptionsSnapshot options)
{
_options = options;
}
public int ShowMaxOrderCount()
{
return _options.Value.MaxOrderCount;
}
}
public class OrderServiceOptions
{
public int MaxOrderCount { get; set; };
}
コントローラにOrderServiceを注入するには:
[HttpGet]
public string Get([FromServices]IOrderService orderService)
{
var res = $"orderService.ShowMaxOrderCount:{orderService.ShowMaxOrderCount()},time={orderService.ShowTime()}";
Console.WriteLine(res);
return res;
}
コンフィグサービスでOrderServiceOptionsとOrderServicesのインジェクションを構成するには、次の手順に従います.
services.Configure(Configuration.GetSection("OrderService"));
services.AddScoped();
IOptionsSnapshotとIOptionsMonitorの違い
ここで注入時にAddScopedスコープ方式を用いたのは,IOptionsSnapshotインタフェースを用いたためである.OptionsSnapshotのライフサイクルは役割ドメインであり、リクエストのたびに構成、更新オプションを再読み込みする必要があります.したがって、構成を変更した後、APIを再要求すると、最新の構成値が表示されます.AddSingletonを選択しようとすると、OrderServiceの一例のライフサイクルがIOptionsSnapshotよりも長いため、ランタイム異常が直接放出されます.
単一のライフサイクルが必要で、検出を変更するシーンが必要な場合はどうすればいいのでしょうか.この場合、IOptionsMonitorを使う必要があります.OptionsMonitorとOptionsSnapshotの違いは次のとおりです.
OptionsMonitorは、OptionsSnapshotと同様に使用されますが、CurrentValueになります.構成ソースを変更すると、OnChangeメソッドがトリガーされます.
_options.OnChange(option =>
{
Console.WriteLine($" , :{_options.CurrentValue.MaxOrderCount}");
});
OptionsMonitorはASP.と組み合わせることもできます.NET Coreノート(3)-構成で紹介されているカスタムデータソースの方法は、IConfigurationProviderがOnReload()イベントをトリガーすると、ここのOnChangeもトリガーされます.
オプションのポスト設定
PostConfigureを使用して、オプションの後期構成を行います.
services.PostConfigure(options =>
{
options.MaxOrderCount += 20;
});
オプションの検証
アプリケーションが誤った構成に読み込まれないように、オプションに検証を追加できます.オプション検証には、次の3つの方法があります.
直接登録検証関数
オプションを追加するにはAddOptionsに置き換える必要があります
//services.Configure(configuration);
services.AddOptions().Bind(configuration).Configure(options =>
{
configuration.Bind(options);
})
.Validate(options => options.MaxOrderCount <= 100, "MaxOrderCount 100");
DataAnnotations
ValidateDataAnnotationsを呼び出します.
services.AddOptions().Bind(configuration).Configure(options =>
{
configuration.Bind(options);
})
.ValidateDataAnnotations();
オプションモデルクラスにAnnotationを追加するには:
public class OrderServiceOptions
{
[Range(0, 100)]
public int MaxOrderCount { get; set; };
}
IValidateOptionsインタフェースの実装
認証サービスの登録:
services.AddOptions().Bind(configuration).Configure(options =>
{
configuration.Bind(options);
})
.Services.AddSingleton,OrderServiceValidateOptions> ();
IValidateOptionsの実装:
public class OrderServiceValidateOptions : IValidateOptions
{
public ValidateOptionsResult Validate(string name, OrderServiceOptions options)
{
if (options.MaxOrderCount > 100)
{
return ValidateOptionsResult.Fail("MaxOrderCount 100");
}
else
{
return ValidateOptionsResult.Success;
}
}
}