Q1. What are the three DI lifetimes?

.NET DI has three primary lifetimes:

  • Transient → new instance every time requested
  • Scoped → one instance per scope, typically one HTTP request
  • Singleton → one instance for the lifetime of the DI container/application

Memory trick:
T = Tiny/statelessS = Scope/requestS = Shared/application

How do you decide which DI lifetime to use?

Best Interview Answer

“I don’t choose a DI lifetime based purely on convention. I look at the service’s state, ownership, construction cost, concurrency requirements, and dependency graph.

Stateless lightweight services are generally transient. Request-specific services and unit-of-work components such as EF Core’s DbContext are scoped. Application-wide immutable or thread-safe state can be singleton.

I also make sure I don’t inject scoped dependencies into singletons because that creates a lifetime mismatch. And in a distributed environment such as ECS, I remember that a .NET singleton is process-local, so shared state belongs in something like Redis rather than an in-memory singleton.”

Lifecycle and where to use

Transient

Keywords: Stateless, Lightweight, Cheap

Use it for lightweight services that don’t need shared state.

Singleton

Keywords: Shared, Immutable, Thread-safe, Application-wide

Use it when the object can safely be shared across requests and doesn’t contain request-specific state.

LifetimeInstance creationTypical lifetimeTypical use
TransientEvery resolutionVery shortStateless/lightweight services
ScopedOnce per scopeUsually HTTP requestDbContext, business services
SingletonOnceApplication/container lifetimeShared thread-safe state, caches

Real World Decision Matrix

Q2. Why is DbContext Scoped?

Keywords: Unit of Work, Change Tracking, Not Thread Safe, Request

DbContext maintains state and change tracking and is designed around a unit-of-work pattern. Sharing it across concurrent requests is unsafe.

Q3. What happens if Singleton depends on Scoped?

Keywords: Lifetime mismatch, Captured dependency, Request state

A longer-lived service can capture a shorter-lived dependency. This is generally invalid and can cause incorrect lifetime behavior.

Q4. Can Scoped depend on Singleton?

Answer: Yes, provided the Singleton is safe for concurrent access and does not depend on scoped/request-specific state.

Q5. Is Singleton shared across ECS tasks?

Answer: No. A .NET Singleton is process/container-local. Three ECS tasks mean three Singleton instances.

Q6. Is Singleton shared across Lambda invocations?

Answer: It may survive across invocations within a reused Lambda execution environment, but it is not globally shared across Lambda environments.

https://youtu.be/AhAxLiGC7Pc?si=xgdo1prO4R9KUN8l&t=9436

going on than than just this but this is the key part so gamar context is getting

2:37:17

registered with the service provider so that later on anywhere in our code base we can go ahead and inject that instance

2:37:23

of gain store context into our code so that we can take advantage of its services now why why is this gain store

2:37:31

context registered with a scope Lifetime well by doing a scope lifetime this ensures that a new instance of the D

2:37:38

context is created and dispos for every single request and this is important for

2:37:44

a few reasons like for for instance database connections are limited and they are a relatively expensive resource

2:37:51

so by having the DV context registered as a scov life time that ensures that

2:37:56

the connections are opened and closed efficiently also DB context is not threat safe so having a single instance

2:38:04

of the context across multiple requests would lead into concurrency issue so we don’t want that we also have to think

2:38:10

about transactions right so having a separate DB context instance per request

2:38:16

makes it easier to manage transactions and ensure data consistency across a single unit of work without interference

2:38:22

from multiple requests and finally reusing the same D context instance

2:38:27

across multiple request could lead to increased memory usage because the DV context keeps track of changes to

2:38:33

entities over its lifetime so by having a scope lifetime that ensures that the DV context is short lift and R reducing

2:38:41

the memory overhead and potentially improving performance all right so now

Saving new entities to the database

2:38:46

that we understand that our gam store context is getting registered as a scope service we can start taking advantage of

2:38:52

it across our code base okay so let’s let’s go ahead and remove this line and let’s put this as it was and what we can

2:38:57

do now is go back into our end points so end points over here games end points

2:39:05

all right let’s collapse this and close that and

2:39:10

we can now go back into our post empo let’s start with post this one over here which is the one

2:39:17

that’s going to allow us to create a brand new game so as you remember the only thing that we’re receiving right now in the Handler for this method is

2:39:24

the the dto the new game dto so now we’re going to go ahead and inject the instance of gain store context that has

2:39:31

been registered in the service provider so for that all we have to do is just add gam store context DB context all

2:39:41

right so at WR time a minut court is going to take care of of resolving and providing us an instance of that context

2:39:48

right here without us having to do anything else and so from here on we

2:39:53

don’t need to be creating uh these DTS manually as we’re doing it here instead

2:39:59

what we want to do is to start creating entities into our DB context so here’s what I’m going to do so I’m going to say

2:40:05

it’s going to be just of type game equals new okay and now I’m going to do

2:40:11

control do here so we can import our Gam store. api. entity Nam space all right

2:40:18

and here is where we’re going to be declaring all of the properties of our brand new game okay and let’s start with

2:40:23

the name so name is going to be new game. name and the next one is going to

2:40:29

be the gener right so we want to assign a gener here now the problem is that if