and*_*lzo 1 c# dependency-injection asp.net-core asp.net-core-2.0
我有这个扩展名
public static class ServiceCollectionExtensions
{
public static IServiceCollection MyExtension(this IServiceCollection serviceCollection)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我需要从这样的服务获取信息:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
var myService = <<HERE>>();
options.TokenValidationParameters = this.GetTokenValidationParameters(myService);
});
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
我尝试获取ServiceProvider之后的邮件var serviceProvider = services.BuildServiceProvider();,然后发送serviceProvider,但这不起作用。
在您致电时services.AddSomething(),尚未从服务集合构建服务提供商。因此,您当时无法实例化服务。幸运的是,有一种在使用依赖项注入时配置服务的方法。
当您这样做时services.AddSomething(options => …),通常会在服务集合中注册一定数量的服务。然后,还将以特殊方式注册所传递的配置操作,以便稍后实例化该服务时,它将能够执行该配置操作以应用配置。
为此,您需要实现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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在您的中注册该类型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>();
Run Code Online (Sandbox Code Playgroud)
实际上,这只是您刚做完services.AddJwtBearer(scheme, options => { … })就被抽象出来时发生的完全相同的事情,因此您无需关心它。但是,通过手动执行此操作,您现在可以拥有更多功能并可以访问完整的依赖项注入服务提供者。