Reputation: 5345
I have to add our custom Basic Authentication Handler, but our implementation requires to pass parameter to it. I am not able to achieve this using DI. Here is part of the code:
// Part of ConfigureServices in Startup.cs
public IServiceProvider ConfigureServices(IServiceCollection services)
{
...
// Some DIs in ConfigureService
services.AddTransient<ICustomService, CustomService>(); //this should be passed later to handler
services.AddHttpContextAccessor();
...
// Adding authentication in ConfigureServices
services.AddAuthentication("Basic")
.AddScheme<CustomBasicAuthenticationOptions, CustomBasicAuthenticationHandler>(
"Basic",
options => new CustomBasicAuthenticationOptions()
{
CustomService = ??? // HOW OT GET CustomService: ICustomService from Container here?
});
...
}
// CustomBasicAuthenticationOptions
public class CustomBasicAuthenticationOptions : AuthenticationSchemeOptions
{
public CustomBasicAuthenticationOptions();
public static string AuthenticationScheme { get; }
public ICustomService CustomService { get; set; } //THIS SHOULD BE INJECTED HERE during AddAuthentication?! How?
...
}
// CustomService and its constructor of
public class CustomService : ICustomService
{
public CustomService(IHttpContextAccessor httpContextAccessor) {
...
}
}
Upvotes: 1
Views: 503
Reputation: 246998
You comment in the original example shows what actually depends on the service
// this should be passed later to handler
Move the service over to the handler as an explicit dependency via constructor injection.
public class CustomBasicAuthenticationHandler : AuthenticationHandler<CustomBasicAuthenticationOptions> {
private readonly ICustomService customService;
public CustomBasicAuthenticationHandler(
ICustomService customService, //<-- NOTE
IOptionsMonitor<BasicAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock
)
: base(options, logger, encoder, clock) {
this.customService = customService;
}
//...
}
And refactor the registration
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//...
// Some DIs in ConfigureService
services.AddTransient<ICustomService, CustomService>(); //this should be passed later to handler
services.AddHttpContextAccessor();
//...
// Adding authentication in ConfigureServices
services.AddAuthentication("Basic")
.AddScheme<CustomBasicAuthenticationOptions, CustomBasicAuthenticationHandler>("Basic", null);
//...
}
Upvotes: 1