.NET'in yerleşik Dependency Injection container'ını günlük olarak kullanıyor olsak da, servis yaşam döngülerinin (lifetime) doğru anlaşılmaması, üretimde fark edilmesi zor hatalara yol açabiliyor.

Üç Temel Yaşam Döngüsü

Transient, her talep edildiğinde yeni bir örnek oluşturuyor. Scoped, aynı HTTP isteği içinde tek bir örnek paylaşıyor. Singleton ise uygulamanın tüm ömrü boyunca tek bir örnek kullanıyor. Bu üçünü doğru seçmek, hem doğruluk hem performans açısından kritik.

services.AddScoped<IOrderRepository, OrderRepository>();
services.AddSingleton<ICacheService, MemoryCacheService>();
services.AddTransient<IEmailBuilder, EmailBuilder>();

Captive Dependency Tuzağı

Bir Singleton servisin içine Scoped bir bağımlılık enjekte etmek, en sık yapılan hatalardan biri. Bu durumda scoped servis, aslında singleton gibi davranmaya başlıyor çünkü sadece bir kez oluşturuluyor — bu da veritabanı bağlantısı gibi kaynaklarda beklenmedik sorunlara yol açabiliyor. .NET, bu hatayı geliştirme ortamında bir uyarıyla yakalıyor, ama üretimde fark edilmeden kalabiliyor.

DbContext Neden Scoped Olmalı?

Entity Framework Core'un DbContext'i varsayılan olarak Scoped kaydediliyor, çünkü bir HTTP isteği içinde tutarlı bir değişiklik takibi (change tracking) sağlaması gerekiyor. Bunu yanlışlıkla Singleton yapmak, farklı istekler arasında veri karışıklığına yol açabiliyor.

Constructor'ı Şişirmemek

Bir sınıfın constructor'ında 8-10 bağımlılık görmek, o sınıfın çok fazla sorumluluk taşıdığının bir işareti. Bu genelde bir Dependency Injection sorunu değil, Tek Sorumluluk prensibinin ihlal edildiğinin göstergesi.

Sonuç

Dependency Injection container'ı "otomatik sihir" gibi görmek yerine, yaşam döngülerinin ne anlama geldiğini anlamak, üretimde ortaya çıkabilecek zor hata ayıklama süreçlerinin önüne geçiyor.