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