How does dependency injection work in ASP.NET Core?
Explain the container, service lifetimes, and where you would not hide a dependency.
Points worth saying
- The host builds one container for the app and a scope per request.
- Singleton, scoped, and transient describe lifetime, not importance.
- Capturing a scoped service from a singleton is a defect, not a style choice.
A full answer
ASP.NET Core creates a root service provider when the host starts. Framework services and your registrations live there. Each incoming HTTP request gets a scope. When the response finishes, that scope is disposed.
Transient services are created every time they are requested. Scoped services are created once per scope, which for a web request means once per request. Singleton services are created once for the root container and shared.
The lifetime rule that matters in an interview is the captive dependency. A singleton must not depend on a scoped service such as a request-bound DbContext. The singleton would keep that instance alive for the process. Fix it by injecting IServiceScopeFactory and creating a scope at the moment of use, or by changing the lifetime.
Prefer constructor injection. It makes the dependency visible in the type and easy to replace in a test. Service location is reasonable at composition roots, such as middleware that needs a scoped service inside InvokeAsync.
Mark your progress
Create a practice profile to mark this question.