DI scopes, threads and processes

1 min read
On trails:ASPNETstep 4/7

A DI scope is a logical unit of work, such as one HTTP request. It is not tied to a thread or a process (lifetimes are in dependency injectionDependency injection and service lifetimesHow ASP.NET Core hands each class what it needs, and how long each instance lives.Opens in a new tab).

Singleton

One instance lives for the process and is shared by all threads, so it must be thread-safe. Separate processes each have their own, so “singleton” means one per process, not per machine.

Scoped

ASP.NET Core creates an IServiceScope per request and disposes it at the end, and every scoped service resolved in it is the same instance, such as a DbContext. It cannot be per thread, because after an await a request may resume on a different pool thread. The scope travels with the request (HttpContext), not the thread. Transient has no tie to any of these.

text
Request starts on thread A -> await DB call -> thread A is freed...other requests run on threads A, B and C...DB call completes -> continuation resumes on thread B(same request, a different thread, the SAME scoped DbContext)

AsyncLocal

AsyncLocal<T> follows the logical async call chain across awaits. [ThreadStatic] and ThreadLocal<T> follow the physical thread and break when a continuation resumes elsewhere. See how a request moves across threadsHow many threads handle one request?One at a time, but not always the same one.Opens in a new tab.