在IServiceCollection扩展中获取服务

我有这个扩展名

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 = <>(); options.TokenValidationParameters = this.GetTokenValidationParameters(myService); }); 

我怎样才能做到这一点?

我尝试在var serviceProvider = services.BuildServiceProvider();之后获取ServiceProvider var serviceProvider = services.BuildServiceProvider(); 然后我发送serviceProvider ,但这不起作用..

在您调用services.AddSomething() ,服务提供程序尚未从服务集合构建。 因此,您无法在那时实例化服务。 幸运的是,有一种方法可以在使用dependency injection时配置服务。

当您执行services.AddSomething(options => …) ,通常会发生一定数量的服务将在服务集合中注册。 然后,传递的配置操作也将以特殊方式注册,以便稍后实例化服务时,它将能够执行该配置操作以应用配置。

为此,您需要实现IConfigureOptions (或实际上IConfigureNamedOptions用于身份validation选项)并将其注册为单例。 出于您的目的,这可能如下所示:

 public class ConfigureJwtBearerOptions : IConfigureNamedOptions { 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, ConfigureJwtBearerOptions>(); 

这实际上与你刚刚执行services.AddJwtBearer(scheme, options => { … })时发生的完全相同,只是抽象掉了,所以你不需要关心它。 但通过手动操作,您现在可以获得更多function并可以访问完整的dependency injection服务提供程序。