ASP.NET Coreオプションモードソースコード学習Options Configure(一)
6593 ワード
前言
ASP.NET Coreの後、私たちの配置はもっと軽量級になりました.ASP.NET Coreでは、構成モデルが大幅に拡張され、強化され、アプリケーション構成が多環境変数構成に格納され、appsettings.jsonユーザ機密などは、アプリケーション内の同じインタフェースで簡単にアクセスできるほか、ASP.NETの新しい構成システムでは、Optionsの強いタイプ設定を使用できます.
強いタイプOptions
ASP.NET CoreにAppSettings[Key]のデフォルトメソッドがない場合は、強いタイプの構成クラスを作成し、構成項目をバインドすることをお勧めします.
public class MyOptions
{
public string Name { get; set; }
public string Url { get; set; }
}
そしてappsettingsでjsonには次の内容が追加されます.
{
"MyOptions":
{
"Name": "TestName",
"Url": "TestUrl"
}
}
クラスへのバインドの設定
コンフィギュレーションサービスメソッドは、クラスにバインドするように構成されています.
public void ConfigureServices(IServiceCollection services)
{
services.Configure(Configuration.GetSection("MyOptions"));
services.AddControllers();
}
MyOptionsは、IOptions<>クラスのインスタンスをコントローラに注入し、ValueプロパティでMyoptionsを取得するだけです.
public class WeatherForecastController : ControllerBase
{
private readonly MyOptions _options;
public WeatherForecastController(IOptions options)
{
_options = options.Value;
}
[HttpGet]
public OkObjectResult Get() {
return Ok(string.Format("Name:{0},Url:{1}", _options.Name,_options.Url));
}
}
Configure
委任構成
//
services.Configure(o => { o.Url = "MyOptions"; o.Name = "Name111"; });
//
services.Configure("Option", o => { o.Url = "MyOptions"; o.Name = "Name111"; }) ;
//
services.ConfigureAll(options =>{ options.Name = "Name1"; options.Url = "Url1";});
プロファイルによる構成
//
services.Configure(Configuration.GetSection("MyOptions"));
//
services.Configure("Option", Configuration.GetSection("MyOptions"));
PostConfigure
PostConfigureは、Configureの登録が完了してから登録されます
services.PostConfigure(o => o.Name = "Name1");
services.PostConfigure("Option", o => o.Name = "Name1");
services.PostConfigureAll(o => o.Name = "Name1");
ソース解析
IConfigureOptionsインタフェース
public interface IConfigureOptions where TOptions : class
{
void Configure(TOptions options);
}
コンフィギュレーションIConfigureOptionsの登録を容易にするための例コンフィギュレーションNamedOptions
public static IServiceCollection Configure(this IServiceCollection services, string name, Action configureOptions)
where TOptions : class
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (configureOptions == null)
{
throw new ArgumentNullException(nameof(configureOptions));
}
services.AddOptions();
services.AddSingleton>(new ConfigureNamedOptions(name, configureOptions));
return services;
}
上記のコードIConfigureOptionsはコンフィギュレーション名edOptionsを実現しています.では、内部ソースのコンフィギュレーション名edOptionsは、私たちが登録したActionを統合したコンフィギュレーションメソッドにパッケージして、後でOptionsインスタンスを作成するときに初期化を容易にします.
public class ConfigureNamedOptions : IConfigureNamedOptions where TOptions : class
{
public ConfigureNamedOptions(string name, Action action)
{
Name = name;
Action = action;
}
public string Name { get; }
public Action Action { get; }
public virtual void Configure(string name, TOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
// Null name is used to configure all named options.
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
}
サービスでConfigure (Configuration.GetSection("MyOptions")); 具体的な名前を指定しない場合、デフォルトは次のコードクリップです.
public virtual void Configure(string name, TOptions options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
// Null name is used to configure all named options.
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
デフォルトではOptionsが使用されています.DefaultName
AddOptionsのデフォルトメソッドでは、いくつかのコアクラスが登録されています.
public static IServiceCollection AddOptions(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>)));
services.TryAdd(ServiceDescriptor.Transient(typeof(IOptionsFactory<>), typeof(OptionsFactory<>)));
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitorCache<>), typeof(OptionsCache<>)));
return services;
}