本文介绍了在IServiceCollection扩展中获取服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个扩展名

public static class ServiceCollectionExtensions
{
    public static IServiceCollection MyExtension(this IServiceCollection serviceCollection)
    {
      ...
    }
}

我需要从这样的服务中获取信息:

and I need to get information from a service like this:

services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
    {
        var myService = <<HERE>>();
        options.TokenValidationParameters = this.GetTokenValidationParameters(myService);
    });

我该怎么做?

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

I tried to get the ServiceProvider after var serviceProvider = services.BuildServiceProvider(); and then I send the serviceProvider, but this doesn't work..

推荐答案

在您调用services.AddSomething()时,尚未从服务集合中构建服务 provider .因此,您当时无法实例化服务.幸运的是,有一种方法可以在使用依赖项注入时配置服务.

At the time you are calling services.AddSomething(), the service provider has not been built from the service collection yet. So you cannot instantiate a service at that time. Fortunately, there is a way to configure services while using dependency injection.

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

When you do services.AddSomething(options => …) what usually happens is that a certain amount of services will be registered with the service collection. And then the passed configuration action will also be registered in a special way, so that when the service is later instantiated, it will be able to execute that configuration action in order to apply the configuration.

为此,您需要实现IConfigureOptions<TOptions>(或者对于身份验证选项实际上是IConfigureNamedOptions<TOptions>)并将其注册为单例.为了您的目的,它可能看起来像这样:

For that, you need to implement IConfigureOptions<TOptions> (or actually IConfigureNamedOptions<TOptions> for authentication options) and register it as a singleton. For your purpose, this could look like this:

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中注册该类型:

You then register that type in your 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 => { … })时,就会发生完全相同的事情,因此您无需在意.但是,通过手动执行此操作,您现在可以拥有更多功能并可以访问完整的依赖项注入服务提供者.

This is actually the exact same thing that happens when you just do services.AddJwtBearer(scheme, options => { … }), just abstracted away, so you don’t need to care about it. But by doing it manually, you now have more power and access to the full dependency injection service provider.

这篇关于在IServiceCollection扩展中获取服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 10:24