DI কী?
Dependency Injection — class নিজে dependency তৈরি করে না, বাইরে থেকে পায়। ASP.NET Core এ built-in।
Without DI ❌
public class UserController {
private UserService _service = new UserService(new SqlDb());
// tightly coupled, untestable
}
With DI ✅
public interface IUserService {
Task<User> GetAsync(int id);
}
public class UserService : IUserService {
private readonly AppDbContext _db;
public UserService(AppDbContext db) => _db = db; // injected!
public Task<User> GetAsync(int id) => _db.Users.FindAsync(id);
}
[ApiController]
public class UsersController : ControllerBase {
private readonly IUserService _service;
public UsersController(IUserService service) => _service = service;
// ⬆ constructor injection
}
Service Lifetimes ⭐
| Lifetime | Scope | ব্যবহার |
|---|---|---|
| Singleton | app-wide একটি instance | config, cache |
| Scoped | per HTTP request | DbContext, repositories ⭐ |
| Transient | প্রতি injection-এ নতুন | lightweight services |
// Program.cs
builder.Services.AddSingleton<IClock, SystemClock>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddTransient<IEmailSender, EmailSender>();
// Or instance
builder.Services.AddSingleton(new MyConfig { Key = "..." });
// Factory
builder.Services.AddScoped<IRepo>(sp => new Repo(sp.GetRequiredService<Db>()));
Built-in Services
// AddControllers, AddDbContext, AddHttpClient, AddLogging,
// AddMemoryCache, AddDistributedRedisCache, AddAuthentication...
builder.Services.AddDbContext<AppDbContext>(opt =>
opt.UseSqlServer(connStr)); // Scoped by default
builder.Services.AddHttpClient<ExternalApiClient>(c => {
c.BaseAddress = new Uri("https://api.example.com");
});
Resolving
// 1. Constructor (preferred)
public class Foo(IBar bar) { } // primary constructor (C# 12)
// 2. From HttpContext
var svc = HttpContext.RequestServices.GetService<IUserService>();
// 3. Service Locator (avoid)
var svc = app.Services.GetRequiredService<IUserService>();
⚠️ Common Pitfalls
- Captive dependency — Singleton-এ Scoped inject করবেন না (DbContext crash)।
- Disposable — Scoped/Transient-এর Dispose() automatically call হয়।