Dependency Injection
Learn how ASP.NET Core's built-in dependency injection container manages object creation and lifetimes.
What is Dependency Injection?
Dependency Injection (DI) is a pattern where a class receives the objects it depends on from the outside, rather than creating them itself. ASP.NET Core has a DI container built in from the ground up.
DI decouples your classes from concrete implementations, making code far easier to test (you can inject a fake/mock dependency) and swap implementations without touching consuming code.
Registering a Service
public interface IEmailService{ void Send(string to, string message);}
public class EmailService : IEmailService{ public void Send(string to, string message) => Console.WriteLine($"Sending to {to}: {message}");}builder.Services.AddScoped<IEmailService, EmailService>();Constructor Injection
Once registered, the DI container automatically provides an instance whenever a class asks for the interface through its constructor.
public class TasksController : ControllerBase{ private readonly IEmailService emailService;
public TasksController(IEmailService emailService) { this.emailService = emailService; // provided automatically }
[HttpPost] public IActionResult Create() { emailService.Send("user@example.com", "New task created!"); return Ok(); }}Service Lifetimes
| Lifetime | Behavior |
|---|---|
| Transient | A new instance every time it's requested |
| Scoped | One instance per HTTP request |
| Singleton | One instance for the entire application lifetime |
AddDbContext registers DbContext as Scoped by default — one instance per request. Never register it as Singleton, since DbContext isn't thread-safe for concurrent requests.
FAQs
No, you can inject a concrete class directly — but injecting against an interface is standard practice since it enables easy testing and swapping implementations.
Summary
- DI lets classes receive their dependencies rather than creating them.
- Services are registered in Program.cs and injected via constructors.
- Transient, Scoped, and Singleton control how long a registered instance lives.