I've just upgraded a .net core app from version 2.2 to 3. Inside the ConfigureServices method in startup.cs I need to resolve a service that is used by the authentication service. I was "building" all the services using "services.BuildServiceProvider()" but .net core 3 complains about the method creating additional copies of the services and suggesting me to dependency injecting services as parameters to 'configure'. I have no idea what the suggestion means and I'd like to understand it.
public virtual void ConfigureServices(IServiceCollection services)
{
// Need to resolve this.
services.AddSingleton<IManageJwtAuthentication, JwtAuthenticationManager>();
var sp = services.BuildServiceProvider(); // COMPLAINING HERE!!
var jwtAuthManager = sp.GetRequiredService<IManageJwtAuthentication>();
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(c =>
{
c.TokenValidationParameters = new TokenValidationParameters
{
AudienceValidator = jwtAuthManager.AudienceValidator,
// More code here...
};
}
}
ASP.NET Core injects objects of dependency classes through constructor or method by using built-in IoC container. The built-in container is represented by IServiceProvider implementation that supports constructor injection by default.
Singleton is a single instance for the lifetime of the application domain. Scoped is a single instance for the duration of the scoped request, which means per HTTP request in ASP.NET. Transient is a single instance per code request.
Built-in IoC container manages the lifetime of a registered service type. It automatically disposes a service instance based on the specified lifetime. Singleton − IoC container will create and share a single instance of a service throughout the application's lifetime.
but .net core 3 complains about the method creating additional copies of the services and suggesting me to dependency injecting services as parameters to 'configure'.
Actually, the ServiceCollection.BuildServiceProvider()
should be invoked by the Host automatically. Your code services.BuildServiceProvider();
will create a duplicated service provider that is different the default one, which might lead to inconsistent service states. See a bug caused by multiple Service Provider here.
To solve this question, configure the options with dependency injection instead of creating a service provider and then locating a service.
For your codes, rewrite them as below:
services.AddSingleton<IManageJwtAuthentication, JwtAuthenticationManager>();
services.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
.Configure<IManageJwtAuthentication>((opts,jwtAuthManager)=>{
opts.TokenValidationParameters = new TokenValidationParameters
{
AudienceValidator = jwtAuthManager.AudienceValidator,
// More code here...
};
});
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With