1. Dependency Injection (Bağımlılık Enjeksiyonu) Nedir?
Dependency Injection (DI), yazılım geliştirmede bağımlılıkları yönetmek ve kodun esnekliğini artırmak için kullanılan bir tasarım desenidir. ASP.NET Core, Dependency Injection’ı yerleşik (built-in) olarak destekler.
1.1. Neden Dependency Injection Kullanmalıyız?
✔ Gevşek Bağlılık (Loose Coupling):
- Kod bileşenleri birbirine sıkı sıkıya bağlı olmadan çalışabilir.
✔ Test Edilebilirlik (Unit Test Desteği):
- Bir bileşeni ayrı ayrı test edebiliriz (Mocking yapabiliriz).
✔ Daha Az Bağımlılık (Decoupling):
- Kod değişiklikleri diğer bileşenleri etkilemez.
✔ Daha Kolay Yönetilebilirlik:
- Nesneler IoC (Inversion of Control) Container tarafından yönetilir.
2. IoC (Inversion of Control) Container Nedir?
Inversion of Control (IoC), nesne oluşturma ve yönetme sürecinin geliştiriciden alınarak bir Container (Kapsayıcı) tarafından yapılmasıdır.
📌 ASP.NET Core’un IoC Container’ı vardır ve bağımlılıkları otomatik olarak enjekte eder.
3. ASP.NET Core’da Dependency Injection Kullanımı
.NET Core’da bağımlılıklar Program.cs dosyasında yapılandırılır.
3.1. Bağımlılık Ekleme (DI Container’a Servis Kaydetme)
Bağımlılıklar Program.cs içinde eklenir:
var builder = WebApplication.CreateBuilder(args);
// Bağımlılıkları ekleme
builder.Services.AddSingleton<IMyService, MyService>();
var app = builder.Build();
app.Run();C#📌 Burada IMyService arayüzü ile MyService sınıfı eşleştirildi.
4. DI Yaşam Döngüsü (Service Lifetimes)
ASP.NET Core üç farklı servis yaşam döngüsü (Service Lifetime) sunar:
| Servis Türü | Açıklama | Kullanım Senaryosu |
|---|---|---|
| Singleton | Uygulama boyunca tek bir nesne oluşturulur. | Konfigürasyon, Cache yönetimi |
| Scoped | Her HTTP isteği için yeni bir nesne oluşturulur. | Veritabanı bağlantıları, Repository’ler |
| Transient | Her çağrıda yeni bir nesne oluşturulur. | Kısa ömürlü servisler, log işlemleri |
📌 Örnek Kullanım:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IMySingletonService, MySingletonService>();
builder.Services.AddScoped<IMyScopedService, MyScopedService>();
builder.Services.AddTransient<IMyTransientService, MyTransientService>();
var app = builder.Build();
app.Run();C#5. Bağımlılığı Controller’a Enjekte Etme
Bir servisi Controller’a enjekte etmek için, öncelikle bir arayüz (Interface) ve sınıf oluşturmalıyız.
5.1. Örnek: Bağımlılık Kullanımı
📌 Arayüz Tanımlama (IMyService.cs)
public interface IMyService
{
string GetMessage();
}C#📌 Servis Sınıfı (MyService.cs)
public class MyService : IMyService
{
public string GetMessage() => "Dependency Injection çalışıyor!";
}C#📌 Servisi DI Container’a Kayıt Etme (Program.cs)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IMyService, MyService>();
var app = builder.Build();
app.MapControllers();
app.Run();C#📌 Bağımlılığı Controller İçinde Kullanma (HomeController.cs)
[ApiController]
[Route("api/[controller]")]
public class HomeController : ControllerBase
{
private readonly IMyService _myService;
public HomeController(IMyService myService)
{
_myService = myService;
}
[HttpGet]
public IActionResult Get()
{
return Ok(_myService.GetMessage());
}
}C#✅ Sonuç: http://localhost:5000/api/home adresine gidildiğinde "Dependency Injection çalışıyor!" cevabını döndürecektir.
6. Bağımlılıkları Constructor Yerine Method’a Enjekte Etme
Bazı durumlarda Dependency Injection’ı doğrudan metodun içine enjekte etmek isteyebiliriz.
📌 Örnek: Service Injection via Method
[ApiController]
[Route("api/[controller]")]
public class HomeController : ControllerBase
{
[HttpGet]
public IActionResult Get([FromServices] IMyService myService)
{
return Ok(myService.GetMessage());
}
}C#✅ Bu yöntem, özellikle tek bir metotta belirli bir servise ihtiyaç duyulduğunda kullanışlıdır.
7. Repository Pattern ile Dependency Injection Kullanımı
Gerçek bir uygulamada, veritabanı işlemleri için Repository Pattern kullanılır.
7.1. Repository Tanımlama (IProductRepository.cs)
public interface IProductRepository
{
List<string> GetAllProducts();
}C#7.2. Repository Implementasyonu (ProductRepository.cs)
public class ProductRepository : IProductRepository
{
public List<string> GetAllProducts()
{
return new List<string> { "Ürün 1", "Ürün 2", "Ürün 3" };
}
}C#7.3. Repository’yi DI Container’a Kayıt Etme (Program.cs)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IProductRepository, ProductRepository>();
var app = builder.Build();
app.MapControllers();
app.Run();C#7.4. Controller İçinde Repository Kullanımı (ProductController.cs)
[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
private readonly IProductRepository _productRepository;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
[HttpGet]
public IActionResult GetProducts()
{
return Ok(_productRepository.GetAllProducts());
}
}C#http://localhost:5000/api/product adresine gidildiğinde şu JSON çıktısını döndürür:
["Ürün 1", "Ürün 2", "Ürün 3"]C#8. Middleware İçinde Dependency Injection Kullanımı
Bazı durumlarda Middleware içinde bağımlılıkları enjekte etmek isteyebiliriz.
📌 Örnek Middleware Kullanımı
public class LoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly IMyService _myService;
public LoggingMiddleware(RequestDelegate next, IMyService myService)
{
_next = next;
_myService = myService;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine("Log Mesajı: " + _myService.GetMessage());
await _next(context);
}
}C#📌 Middleware Kullanımı (Program.cs)
app.UseMiddleware<LoggingMiddleware>();C#