我有这个扩展名
public static class ServiceCollectionExtensions
{
public static IServiceCollection MyExtension(this IServiceCollection serviceCollection)
{
...
}
}
我需要从这样的服务中获取信息:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
var myService = <<HERE>>();
options.TokenValidationParameters = this.GetTokenValidationParameters(myService);
});
我该怎么做?
我尝试在ServiceProvider
之后获取var serviceProvider = services.BuildServiceProvider();
然后发送serviceProvider
,但这不起作用..
答案 0 :(得分:4)
当您呼叫services.AddSomething()
时,尚未从服务集合构建服务提供程序。因此,您无法在当时实例化服务。幸运的是,有一种方法可以在使用依赖注入时配置服务。
当您执行services.AddSomething(options => …)
时,通常会发生一定数量的服务将在服务集合中注册。然后传递的配置 action 也将以特殊方式注册,以便稍后实例化服务时,它将能够执行该配置操作以应用配置。
为此,您需要实现IConfigureOptions<TOptions>
(或实际IConfigureNamedOptions<TOptions>
用于身份验证选项)并将其注册为单例。为了您的目的,这可能是这样的:
public class ConfigureJwtBearerOptions : IConfigureNamedOptions<JwtBearerOptions>
{
private readonly IMyService _myService;
public ConfigureJwtBearerOptions(IMyService myService)
{
// ConfigureJwtBearerOptionsis constructed from DI, so we can inject anything here
_myService = myService;
}
public void Configure(string name, JwtBearerOptions options)
{
// check that we are currently configuring the options for the correct scheme
if (name == JwtBearerDefaults.AuthenticationScheme)
{
options.TokenValidationParameters = myService.GetTokenValidationParameters();
}
}
public void Configure(JwtBearerOptions options)
{
// default case: no scheme name was specified
Configure(string.Empty, options);
}
}
然后在Startup
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
// add JwtBearer but no need to pass options here
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, configureOptions: null);
// instead we are registering our configuration type to configure it later
services.AddSingleton<IConfigureOptions<JwtBearerOptions>, ConfigureJwtBearerOptions>();
这实际上就是你刚刚做services.AddJwtBearer(scheme, options => { … })
时发生的事情,只是抽象出来,所以你不需要关心它。但通过手动操作,您现在可以获得更多功能并可以访问完整的依赖注入服务提供程序。