.net core 3 依赖注入服务作为“配置”的参数

Posted

技术标签:

【中文标题】.net core 3 依赖注入服务作为“配置”的参数【英文标题】:.net core 3 dependency injecting services as parameters to 'configure' 【发布时间】:2019-10-03 05:20:19 【问题描述】:

我刚刚将一个 .net 核心应用程序从 2.2 版升级到了 3 版。 在 startup.cs 的 ConfigureServices 方法中,我需要解析身份验证服务使用的服务。 我正在使用“services.BuildServiceProvider()”“构建”所有服务,但 .net core 3 抱怨该方法创建了服务的额外副本,并建议我将依赖注入服务作为“配置”的参数。 我不知道这个建议是什么意思,我想理解它。

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】:

但 .net core 3 抱怨该方法创建了额外的服务副本,并建议我将依赖注入服务作为“配置”的参数。

实际上,ServiceCollection.BuildServiceProvider() 应该由主机自动调用。您的代码services.BuildServiceProvider(); 将创建一个重复 服务提供者,该服务提供者不同 默认服务提供者,这可能导致不一致 服务状态。见a bug caused by multiple Service Provider here。

要解决这个问题,configure the options with dependency injection 而不是创建服务提供者然后定位服务。

对于你的代码,改写如下:

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 服务注入到选项中? @LucaMarangon 对于特定的身份验证处理程序(例如 JwtBearerHandler),将会有一个单例 AuthenticationSchemeOptions(例如 JwtBearerOptions)。我们可以通过 AddScheme&lt;&gt;(action) 配置它(例如 AddJwtBearer(action)) ,或者通过选项构建器配置选项,这样我们就可以在不构建服务提供者的情况下注入服务。在这种情况下,只要您的身份验证服务被调用,您的 jwtAuthManager 服务就会被调用。

以上是关于.net core 3 依赖注入服务作为“配置”的参数的主要内容,如果未能解决你的问题,请参考以下文章

.NET Core Web API使用依赖注入(DI)进行服务配置一

ASP.NET Core 依赖注入(DI)

[ASP.NET Core 3框架揭秘] 依赖注入:一个Mini版的依赖注入框架

如何为 .NET Core 3.0 中 WPF 配置依赖注入 ?

.NET Core 3 Worker 服务设置依赖注入

WPF .Net Core 3.1 依赖注入/服务参考问题