Dependency injection in ASP.NET Core
Why DI exists, how to register services, the three lifetimes, and the mistakes interviewers ask about.
Dependency injection in ASP.NET Core
The idea
A class shouldn’t create the things it depends on. It asks for them in its constructor, and something outside provides them. That something is the DI container.
IEmailSender sender = new ConsoleEmailSender();
var orders = new OrderService(sender);
orders.PlaceOrder("book");
interface IEmailSender { void Send(string text); }
class ConsoleEmailSender : IEmailSender { public void Send(string text) => Console.WriteLine(text); }
class OrderService(IEmailSender sender)
{
public void PlaceOrder(string item) => sender.Send($"Ordered: {item}");
}
It prints Ordered: book. The demo wires the objects by hand; in ASP.NET Core the container does it. Swap ConsoleEmailSender for a fake in a unit test, and OrderService doesn’t change.
Registering services
In Program.cs, tell the container which class to use for each interface:
builder.Services.AddTransient<IClock, SystemClock>();builder.Services.AddScoped<IOrderRepository, SqlOrderRepository>();builder.Services.AddSingleton<ICache, MemoryCache>();
Controllers, minimal API handlers and other services then just list what they need in their constructors or parameters.
The three lifetimes
| Lifetime | One object per… | Typical use |
|---|---|---|
| Transient | every time it is asked for (resolved) | small stateless helpers |
| Scoped | HTTP request | DbContext, unit of work |
| Singleton | whole app | caches, configuration, clients meant to be shared |
Mistakes interviewers ask about
- Captive dependency (a longer-lived service holding a shorter-lived one): a singleton that takes a scoped service in its constructor keeps it for the whole app. A
DbContextshared by all requests is not thread-safe and breaks. newinside the class: creating dependencies withnewhides them and makes testing hard.- Too many constructor parameters: a sign the class does too much.
Read more: https://roadmap.sh/aspnet-core
#tip · TIP-047
Write a comment