The application layer
Dependency injection and lifetimes
Singleton, scoped and transient: the wrong choice causes silent data leaks or failing requests.
Understand the concept
With dependency injection (DI) a class does not create the objects it needs; it asks for them in its constructor and the container supplies them. The class depends on an interface rather than a concrete implementation, and a test can pass a fake.
Each service is registered with a lifetime. Singleton: one instance for the app’s lifetime; it must be stateless and thread-safe (configuration, the HttpClient factory). Scoped: one instance per HTTP request; DbContext is scoped because it tracks changes within a request and is released when the request ends. Transient: a new instance every time it is requested; for light, stateless helpers.
The most dangerous mistake is a captive dependency: if a singleton takes a scoped service in its constructor, that scoped instance lives for the whole app. A DbContext captured in a singleton is shared by different users’ requests, causing threading errors and mixed data. In development ASP.NET Core catches this with scope validation.
Lifetime decides which requests share an object.
Keeping a DbContext or per-user state inside a singleton service.
One topic. Three levels of depth.
builder.Services.AddScoped<IPostQueries, PostQueries>();
public class PostsController(IPostQueries posts) : ControllerBase { … }The controller asks for the interface; the container supplies a PostQueries per request.
This page connects to no real server or database. Code samples are illustrative for .NET 8, Next.js and SQL Server; timings are example values in the simulation, not measurements. Try samples only in your own development environment; never share real connection strings, tokens or passwords.
Try it yourself first.
In production you occasionally see ‘A second operation was started on this context instance before a previous operation completed’. Where might the DbContext be wrongly registered?
Show the solution and explanation
DbContext’i alan bir servis singleton olarak kaydedilmiş (esir bağımlılık)
veya aynı istek içinde paralel Task.WhenAll ile aynı DbContext kullanılıyor.
DbContext iş parçacığı güvenli değildir: istek başına bir örnek, eşzamanlı kullanım yok.The error shows the DbContext used by multiple operations at once, usually caused by a wrong lifetime.