根据AddOptions 的代码,我们对此扩展方法进行了以下注册:
public static IServiceCollection AddOptions(this IServiceCollection services)
{
ThrowHelper.ThrowIfNull(services);
services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(UnnamedOptionsManager<>)));
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;
}
所以当我们注入IOtion<TOption> 时,它会尝试注入它的一个实例UnnamedOptionManager<TOption>。并且要创建它的实例,它的构造函数需要注入OptionsFactory,OptionFactory 的构造函数本身需要注入所有配置操作和配置后操作和验证。这都是需要的。所以剩下的就是我们如何注册IConfigureOptions。可以通过以下方式使用 Options Builder 和使用服务集合的Configure/PostConfigure/Validate/ConfigureOptions 扩展方法:
1- 使用选项生成器:在这种方法中,我们使用它的构造函数创建一个选项生成器,它需要服务集合和选项名称(或使用返回选项生成器的service.AddOptions<TOptions>() 扩展方法)。然后我们使用 Configure、PostConfigure 和 Validate 或 Bind 方法以链式方式配置此选项 Builder(这些方法不同于为服务集合定义的(Configure、PostConfigure、ConfigureOptions、ConfigureAll、PostConfigureAll)作为扩展方法)。 OptionsBuilder 的每个方法都在内部执行此操作:
service.AddTransient<IConfigureOptions>() 并致电 AddOptions()。
2-使用为服务容器定义的扩展方法(Configure,PostConfigure,ConfigureOptions,ConfigureAll,PostConfigureAll),几乎如下:
// 配置服务集合的扩展方法
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string? name, Action<TOptions> configureOptions)
where TOptions : class
{
ThrowHelper.ThrowIfNull(services);
ThrowHelper.ThrowIfNull(configureOptions);
services.AddOptions();
services.AddSingleton<IConfigureOptions<TOptions>>(new ConfigureNamedOptions<TOptions>(name, configureOptions));
return services;
}
所以问题的答案是AddOptions()的定义和OptionsBuilder的每个方法的定义。