ASP.NET Core Dependency Injection – Cannot consume scoped service

When working with ASP.NET Core and it’s Dependency Injection container, you will likely run into an error that’s similar to this one:

Some services are not able to be constructed (Error while validating the service descriptor ‘ServiceType: AspNetCoreDi.IMyConnectionManager Lifetime: Singleton ImplementationType: AspNetCoreDi.MyConnectionManager’: Cannot consume scoped service ‘AspNetCoreDi.IMyScopedService’ from singleton ‘AspNetCoreDi.IMyConnectionManager’.)

This happens when you have something like this:

So, what’s going on here? Your singleton IMyConnectionManager would get an instance of IMyScopedService, and every other time you try to get an instance of IMyConnectionManager, since it’s singleton it will have the same state, and it will always contain the same instance of IMyScopedService, meaning that IMyScopedService effectively becomes a singleton inside of MyConnectionManager.

Recommended reading: Dependency injection in ASP.NET Core

In ASP.NET Core we have 3 types of service lifetimes:

  1. Singleton – they’re created first time they’re request, and every time after that the same instance will be reused
  2. Scoped – they’re created once per the request (connection)
  3. Transient are created every time you request them from the DI container

You should almost never consume scoped service or transient service from a singleton. You should also avoid consuming transient service from a scoped service.

What is happening when you consume scoped service from a singleton service is known as a captive dependency. It occurs when a service intended to live for a short(er) amount of time gets held by a service that lives for a more extended amount of time. This almost always suggests that you should change something in your design.

 

Ibrahim Šuta

Software Consultant interested and specialising in ASP.NET Core, C#, JavaScript, Angular, React.js.