Dependency Injection
Provides an object with its dependencies from external sources instead of having it build them itself.
Context
A class that constructs its dependencies using new becomes coupled to them. You cannot mock or change implementations.
Problem
Coupling + zero testability.
Solution
Pass dependencies through the constructor; a container resolves them.
#Example in C# — .NET Native DI
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IClock, SystemClock>();
builder.Services.AddScoped<IOrderRepository, EfOrderRepository>();
builder.Services.AddScoped<PostPublisher>();
// Service consumes dependencies via ctor
public class PostPublisher
{
private readonly IOrderRepository _repo;
private readonly IClock _clock;
public PostPublisher(IOrderRepository r, IClock c) { _repo = r; _clock = c; }
}#Lifetimes in .NET
| Lifetime | Lives for | Typical Use |
|---|---|---|
| Singleton | Entire app | Caches, clocks, options |
| Scoped | One HTTP request / scope | DbContext, repositories |
| Transient | Every resolution | Stateless services |
When NOT to use it
- For primitive types or data records: use normal parameters.
- DI via property (setter) → fragile, prefer constructor.
#extra #ioc #di