值得注意的是ConfigureAll如果你此方法去注入一个Name 为null 的 Configure Action包装类逻辑体现在ConfigureNamedOptions.Configure/PostConfigureOptions.Configure方法上。,官方说法:“Configure ALL options instances, both named and default”翻译后扩展方法将配置应用于所有选项,包括命名实例和默认实例。
public static class OptionsServiceCollectionExtensions
{
...
public static IServiceCollection Configure<TOptions>(this IServiceCollection services!!, string? name, Action<TOptions> configureOptions!!)
where TOptions : class
{
services.AddOptions();
services.AddSingleton<IConfigureOptions<TOptions>>(new ConfigureNamedOptions<TOptions>(name, configureOptions));
return services;
}
public static IServiceCollection PostConfigure<TOptions>(this IServiceCollection services!!, string? name, Action<TOptions> configureOptions!!)
where TOptions : class
{
services.AddOptions();
services.AddSingleton<IPostConfigureOptions<TOptions>>(new PostConfigureOptions<TOptions>(name, configureOptions));
return services;
}
...
}
public class ConfigureNamedOptions<TOptions> : IConfigureNamedOptions<TOptions> where TOptions : class
{
public ConfigureNamedOptions(string? name, Action<TOptions>? action)
{
Name = name;
Action = action;
}
public virtual void Configure(string? name, TOptions options!!)
{
// Null name is used to configure all named options.// Name的过滤以及Configure 逻辑就是在这里体现的
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
}
public class PostConfigureOptions<TOptions> : IPostConfigureOptions<TOptions> where TOptions : class
{
public PostConfigureOptions(string? name, Action<TOptions>? action)
{
Name = name;
Action = action;
}
public virtual void PostConfigure(string? name, TOptions options!!)
{
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
}
以下代码为AddOptions 的服务注册逻辑。
public static class OptionsServiceCollectionExtensions
{
...
public static OptionsBuilder<TOptions> AddOptions<TOptions>(this IServiceCollection services!!, string? name)
where TOptions : class
{
services.AddOptions();
return new OptionsBuilder<TOptions>(services, name);
}
...
}
public class OptionsBuilder<TOptions> where TOptions : class
{
...
public virtual OptionsBuilder<TOptions> Configure<TDep>(Action<TOptions, TDep> configureOptions!!) where TDep : class
{
Services.AddTransient<IConfigureOptions<TOptions>>(sp =>
new ConfigureNamedOptions<TOptions, TDep>(Name, sp.GetRequiredService<TDep>(), configureOptions));
return this;
}
...
}
public class ConfigureNamedOptions<TOptions, TDep> : IConfigureNamedOptions<TOptions> {
...
public ConfigureNamedOptions(string? name, TDep dependency, Action<TOptions, TDep>? action)
{
Name = name;
Action = action;
Dependency = dependency;
}
public virtual void Configure(string? name, TOptions options!!)
{
// Null name is used to configure all named options.
if (Name == null || name == Name)
{
Action?.Invoke(options, Dependency);
}
}
...
}
总结
值得注意的是ConfigureAll如果你此方法去注入一个Name 为null 的 Configure Action包装类逻辑体现在ConfigureNamedOptions.Configure/PostConfigureOptions.Configure方法上。,官方说法:“Configure ALL options instances, both named and default”翻译后扩展方法将配置应用于所有选项,包括命名实例和默认实例。
public static class OptionsServiceCollectionExtensions
{
...
public static IServiceCollection Configure<TOptions>(this IServiceCollection services!!, string? name, Action<TOptions> configureOptions!!)
where TOptions : class
{
services.AddOptions();
services.AddSingleton<IConfigureOptions<TOptions>>(new ConfigureNamedOptions<TOptions>(name, configureOptions));
return services;
}
public static IServiceCollection PostConfigure<TOptions>(this IServiceCollection services!!, string? name, Action<TOptions> configureOptions!!)
where TOptions : class
{
services.AddOptions();
services.AddSingleton<IPostConfigureOptions<TOptions>>(new PostConfigureOptions<TOptions>(name, configureOptions));
return services;
}
...
}
public class ConfigureNamedOptions<TOptions> : IConfigureNamedOptions<TOptions> where TOptions : class
{
public ConfigureNamedOptions(string? name, Action<TOptions>? action)
{
Name = name;
Action = action;
}
public virtual void Configure(string? name, TOptions options!!)
{
// Null name is used to configure all named options.// Name的过滤以及Configure 逻辑就是在这里体现的
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
}
public class PostConfigureOptions<TOptions> : IPostConfigureOptions<TOptions> where TOptions : class
{
public PostConfigureOptions(string? name, Action<TOptions>? action)
{
Name = name;
Action = action;
}
public virtual void PostConfigure(string? name, TOptions options!!)
{
if (Name == null || name == Name)
{
Action?.Invoke(options);
}
}
}
以下代码为AddOptions 的服务注册逻辑。
public static class OptionsServiceCollectionExtensions
{
...
public static OptionsBuilder<TOptions> AddOptions<TOptions>(this IServiceCollection services!!, string? name)
where TOptions : class
{
services.AddOptions();
return new OptionsBuilder<TOptions>(services, name);
}
...
}
public class OptionsBuilder<TOptions> where TOptions : class
{
...
public virtual OptionsBuilder<TOptions> Configure<TDep>(Action<TOptions, TDep> configureOptions!!) where TDep : class
{
Services.AddTransient<IConfigureOptions<TOptions>>(sp =>
new ConfigureNamedOptions<TOptions, TDep>(Name, sp.GetRequiredService<TDep>(), configureOptions));
return this;
}
...
}
public class ConfigureNamedOptions<TOptions, TDep> : IConfigureNamedOptions<TOptions> {
...
public ConfigureNamedOptions(string? name, TDep dependency, Action<TOptions, TDep>? action)
{
Name = name;
Action = action;
Dependency = dependency;
}
public virtual void Configure(string? name, TOptions options!!)
{
// Null name is used to configure all named options.
if (Name == null || name == Name)
{
Action?.Invoke(options, Dependency);
}
}
...
}
总结