.NET Core 3如何将依赖注入的服务作为参数传递给“configure”函数

8

我刚刚将一个.NET Core应用程序从2.2版本升级到3版本。 在startup.cs文件中的ConfigureServices方法内,我需要解析一个由身份验证服务使用的服务。 我之前使用"services.BuildServiceProvider()"构建了所有的服务,但是.NET Core 3提示该方法会创建额外的服务副本,并建议我将服务作为参数进行依赖注入到'configure'方法中。 我不知道这个建议是什么意思,我想要理解它。

public virtual void ConfigureServices(IServiceCollection services)
{
    // Need to resolve this.
    services.AddSingleton<IManageJwtAuthentication, JwtAuthenticationManager>();

    var sp = services.BuildServiceProvider(); // COMPLAINING HERE!!
    var jwtAuthManager = sp.GetRequiredService<IManageJwtAuthentication>();

    services
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(c =>
        {
            c.TokenValidationParameters = new TokenValidationParameters
            {
                AudienceValidator = jwtAuthManager.AudienceValidator,
                // More code here...
            };
        }
}
1个回答

13
但是 .net core 3 抱怨这个方法会创建额外的服务副本,并建议我将服务作为参数进行依赖注入到'configure'中。实际上,ServiceCollection.BuildServiceProvider() 应该由 主机自动 调用。你的代码 services.BuildServiceProvider(); 将创建一个重复的服务提供程序,它与默认的服务提供程序不同,这可能导致不一致的服务状态。请参见此处多个服务提供程序引起的 bug。为了解决这个问题,请使用依赖注入配置选项,而不是创建服务提供程序然后查找服务。对于你的代码,请重写成以下格式:
services.AddSingleton<IManageJwtAuthentication, JwtAuthenticationManager>();

services.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
    .Configure<IManageJwtAuthentication>((opts,jwtAuthManager)=>{
        opts.TokenValidationParameters = new TokenValidationParameters
        {
            AudienceValidator = jwtAuthManager.AudienceValidator,
            // More code here...
        };
    });

services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer();

所以基本上当它“运行”身份验证服务时,它会将jwtAuthManager服务注入选项中? - Luca Marangon
@LucaMarangon 对于特定的身份验证处理程序(例如JwtBearerHandler),将有一个单例AuthenticationSchemeOptions(例如JwtBearerOptions)。我们可以通过AddScheme<>(action)(例如AddJwtBearer(action))进行配置,或者通过选项构建器进行配置,以便我们可以在不构建服务提供程序的情况下注入服务。在这种情况下,每当调用身份验证服务时,都会调用您的jwtAuthManager服务。 - itminus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接