I have this extension
public static class ServiceCollectionExtensions
{
public static IServiceCollection MyExtension(this IServiceCollection serviceCollection)
{
...
}
}
and I need to get information from a service like this:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
var myService = <<HERE>>();
options.TokenValidationParameters = this.GetTokenValidationParameters(myService);
});
how can I do that?
I tried to get the ServiceProvider
after var serviceProvider = services.BuildServiceProvider();
and then I send the serviceProvider
, but this doesn't work..
At the time you are calling
services.AddSomething()
, the service provider has not been built from the service collection yet. So you cannot instantiate a service at that time. Fortunately, there is a way to configure services while using dependency injection.When you do
services.AddSomething(options => …)
what usually happens is that a certain amount of services will be registered with the service collection. And then the passed configuration action will also be registered in a special way, so that when the service is later instantiated, it will be able to execute that configuration action in order to apply the configuration.For that, you need to implement
IConfigureOptions<TOptions>
(or actuallyIConfigureNamedOptions<TOptions>
for authentication options) and register it as a singleton. For your purpose, this could look like this:You then register that type in your
Startup
:This is actually the exact same thing that happens when you just do
services.AddJwtBearer(scheme, options => { … })
, just abstracted away, so you don’t need to care about it. But by doing it manually, you now have more power and access to the full dependency injection service provider.