I have a custom AuthenticationHandler<>
implementation that depends on application service. Is there a way to resolve dependencies of AuthenticationHandler
from Simple Injector? Or maybe cross-wire registration so that applications services can be resolved from IServiceCollection
?
Sample implementation can look as follows for simplicity:
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 => { });
Current solution is to manually cross-wire application service which is not quite convenient:
services.AddTransient(provider => container.GetInstance<ITokenDecryptor>());
Tao's answer is right. The easiest way to implement this is to cross wire the AuthHandler
to Simple Injector.
This can be done as follows:
// 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);