如何将应用程序服务注入 AuthenticationHandler
How to inject application service into AuthenticationHandler
我有一个依赖于应用程序服务的自定义 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 => { });
目前的解决方案是手动跨线申请服务,不太方便:
services.AddTransient(provider => container.GetInstance<ITokenDecryptor>());
maybe cross-wire registration so that applications services can be
resolved from IServiceCollection?
不,.Net Core不可能自动解析来自Simple Injector的服务。
Cross-wiring is a one-way process. By using
AutoCrossWireAspNetComponents, ASP.NET’s configuration system will not
automatically resolve its missing dependencies from Simple Injector.
When an application component, composed by Simple Injector, needs to
be injected into a framework or third-party component, this has to be
set up manually by adding a ServiceDescriptor to the
IServiceCollection that requests the dependency from Simple Injector.
This practice however should be quite rare.
参考:Cross-wiring ASP.NET and third-party services。
根据上面的建议,您需要在IServiceCollection
中注册服务。您目前已经实现了。
陶老师的回答是对的。实现这一点的最简单方法是 将 和 AuthHandler
连接到 Simple Injector。
这可以按如下方式完成:
// 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);
我使用的是 .Net 5,在我从旧的 .net 核心应用程序升级后,Steven 提供的原始版本不再适用于我。我必须:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication("MyScheme")
.AddScheme<ApiKeyOptions, ApiKeyAuthenticationHandler>("MyScheme", o => { });
var authHandlerDescriptor = services
.First(s => s.ImplementationType == typeof(ApiKeyAuthenticationHandler));
services.Remove(authHandlerDescriptor);
services.AddTransient(c => container.GetInstance<ApiKeyAuthenticationHandler>());
}
我有一个依赖于应用程序服务的自定义 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 => { });
目前的解决方案是手动跨线申请服务,不太方便:
services.AddTransient(provider => container.GetInstance<ITokenDecryptor>());
maybe cross-wire registration so that applications services can be resolved from IServiceCollection?
不,.Net Core不可能自动解析来自Simple Injector的服务。
Cross-wiring is a one-way process. By using AutoCrossWireAspNetComponents, ASP.NET’s configuration system will not automatically resolve its missing dependencies from Simple Injector. When an application component, composed by Simple Injector, needs to be injected into a framework or third-party component, this has to be set up manually by adding a ServiceDescriptor to the IServiceCollection that requests the dependency from Simple Injector. This practice however should be quite rare.
参考:Cross-wiring ASP.NET and third-party services。
根据上面的建议,您需要在IServiceCollection
中注册服务。您目前已经实现了。
陶老师的回答是对的。实现这一点的最简单方法是 将 和 AuthHandler
连接到 Simple Injector。
这可以按如下方式完成:
// 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);
我使用的是 .Net 5,在我从旧的 .net 核心应用程序升级后,Steven 提供的原始版本不再适用于我。我必须:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddAuthentication("MyScheme")
.AddScheme<ApiKeyOptions, ApiKeyAuthenticationHandler>("MyScheme", o => { });
var authHandlerDescriptor = services
.First(s => s.ImplementationType == typeof(ApiKeyAuthenticationHandler));
services.Remove(authHandlerDescriptor);
services.AddTransient(c => container.GetInstance<ApiKeyAuthenticationHandler>());
}