C# 如何将应用程序服务注入AuthenticationHandler

C# 如何将应用程序服务注入AuthenticationHandler,c#,asp.net-core,simple-injector,C#,Asp.net Core,Simple Injector,我有一个自定义的AuthenticationHandler实现,它依赖于应用程序服务。有没有一种方法可以从Simple Injector解决AuthenticationHandler的依赖关系?或者可以跨线注册,以便可以从IServiceCollection解析应用程序服务 为了简单起见,示例实现可以如下所示: public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions> { pri

我有一个自定义的
AuthenticationHandler
实现,它依赖于应用程序服务。有没有一种方法可以从Simple Injector解决
AuthenticationHandler
的依赖关系?或者可以跨线注册,以便可以从
IServiceCollection
解析应用程序服务

为了简单起见,示例实现可以如下所示:

public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    private readonly ITokenDecryptor tokenDecryptor;

    public SecurityTokenAuthHandler(ITokenDecryptor tokenDecryptor,
        IOptionsMonitor<AuthenticationSchemeOptions> options, 
        ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) :
        base(options, logger, encoder, clock) =>
        this.tokenDecryptor = tokenDecryptor;

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync() =>
        return tokenDecryptor.Decrypt(this);
}

...

services.AddAuthentication("Scheme")
    .AddScheme<AuthenticationSchemeOptions, AuthHandler>("Scheme", options => { });
公共类AuthHandler:AuthenticationHandler
{
专用只读ITokenDecryptor令牌解密器;
public SecurityTokenAuthHandler(ITokenDecryptor tokenDecryptor,
IOPTIONS监视器选项,
iLogger(出厂记录器、URLCoder编码器、ISystemClock时钟):
基本(选项、记录器、编码器、时钟)=>
this.tokenDecryptor=tokenDecryptor;
受保护的覆盖异步任务handleAuthenticateAync()=>
返回tokenDecryptor.Decrypt(this);
}
...
服务。添加身份验证(“方案”)
.AddScheme(“Scheme”,选项=>{});
目前的解决方案是手动跨线应用服务,这不是很方便:

services.AddTransient(provider => container.GetInstance<ITokenDecryptor>());
services.AddTransient(provider=>container.GetInstance());
可能是跨线注册,这样应用程序服务就可以 从IServiceCollection中解决

不,对于.Net内核来说,自动解析来自简单注入器的服务是不可能的

交叉布线是一个单向过程。利用 AutoCrossWireAspNetComponents,ASP.NET的配置系统将不会 从Simple Injector自动解决其缺少的依赖项。 当一个由简单注入器组成的应用程序组件需要 要注入框架或第三方组件,必须 通过将ServiceDescriptor添加到 IServiceCollection,从简单注入器请求依赖项。 然而,这种做法应该相当罕见

参考文献:


根据上面的建议,您需要在
IServiceCollection
中注册服务。您目前已经实现了。

Tao的答案是正确的。实现这一点的最简单方法是将
AuthHandler
交叉连接到简单注入器

这可以通过以下方式完成:

// Your original configuration:
services.AddAuthentication("Scheme")
    .AddScheme<AuthenticationSchemeOptions, AuthHandler>("Scheme", options => { });

// Cross wire AuthHandler; let Simple Injector create AuthHandler.
// Note: this must be done after the call to AddScheme. Otherwise it will
// be overridden by ASP.NET.
services.AddTransient(c => container.GetInstance<AuthHandler>());

// Register the handler with its dependencies (in your case ITokenDecryptor) with 
// Simple Injector
container.Register<AuthHandler>();
container.Register<ITokenDecryptor, MyAwesomeTokenDecryptor>(Lifestyle.Singleton);
//您的原始配置:
服务。添加身份验证(“方案”)
.AddScheme(“Scheme”,选项=>{});
//交叉导线;让简单的注入器创建AuthHandler。
//注意:这必须在调用AddScheme后完成。否则它会的
//被ASP.NET覆盖。
AddTransient(c=>container.GetInstance());
//将处理程序及其依赖项(在您的例子中是ITokenDecryptor)注册到
//简易注射器
container.Register();
容器。登记(生活方式。单身);

太好了,基本上这是更进一步的一步:注册处理程序本身,而不是服务,这使得维护更加容易。谢谢你对订购的提示!在NetCore3.1中,在我使用services.AddTransient之后,服务有2个AuthHandler注册,并且总是第一个注册被选中。我建议在添加自己的AuthHandler注册之前删除第一个AuthHandler注册。也许您可以更新您的答案,以反映net core 3.1中的变化。所提供的解决方案的其余部分工作正常,谢谢。