Yükleniyor

NET Core’da Service Lifetimes: Singleton, Scoped ve Transient Derinlemesine İnceleme

Blog Kategorileri

.Net Core Mimariler
Tasarım Desenleri
ORM Araçları
API Geliştirme
Web Geliştirme
Veritabanları
2 Aralık 2025 Salı
NET Core’da Service Lifetimes: Singleton, Scoped ve Transient Derinlemesine İnceleme

Modern .NET Core uygulamaları, bağımlılık enjeksiyonunu (Dependency Injection – DI) temel mimari taşlarından biri olarak kullanır. Uygulamanın ölçeklenebilir, test edilebilir ve yönetilebilir olması için servislerin yaşam döngüsü doğru belirlenmelidir. İşte tam bu noktada devreye service lifetime kavramı girer.

Bu yazıda, .NET Core’un DI konteyneri tarafından desteklenen üç temel yaşam döngüsünü; Singleton, Scoped ve Transient servisleri, çalışma zamanına etkileri ve doğru kullanım alanlarıyla birlikte ele alacağım.

Dependency Injection ve Service Lifetime Neden Önemlidir?

Servis yaşam süreleri, uygulamanın:

  1. Performansını

  2. Bellek tüketimini

  3. Thread ve request yönetimini

  4. Veri tutarlılığını

doğrudan etkiler.

Yanlış seçilmiş bir lifetime, özellikle multi-thread senaryolarda  memory leak'lere, gereksiz CPU yüküne ve istenmeyen state paylaşımlarına yol açabilir Bu nedenle hangi servisin hangi yaşam döngüsünde olması gerektiğini bilmek, profesyonel bir .NET Core uygulamasının temel gerekliliğidir.

Service Lifetime Türleri​

Lifetime
Ne Zaman Oluşur?
Ne Zaman Yok Olur?
Her Request İçin Yeni Örnek?
Thread-Safe Gerekli mi?
Singleton
Uygulama başlarken / ilk ihtiyaçta
Uygulama kapanınca
Hayır
Evet
Scoped
Her HTTP request başladığında
Request bittiğinde
Evet
Kısmen
Transient
Her talepte
Talep sonrası
Evet, her defasında
Hayır

Singleton Service​

Singleton servisler uygulama boyunca yalnızca bir kez örneklenir. DI konteyner içinde tek bir instance oluşturulur ve tüm uygulamada paylaşılır.

services.AddSingleton<IMyService, MyService>();

Kullanım Senaryoları

  1. Konfigürasyon yöneten sınıflar

  2. Hafif, thread-safe utility komponentleri

  3. Cache yöneticileri

  4. Log yazıcıları

  5. Sabit veri üreten servisler

Avantajlar

  1. Minimal bellek tahsisi — tek örnek

  2. Yüksek performans — tekrar oluşturulmaz

Riskler

  1. Thread-safe olmayan kodlarda yarış koşullarına neden olabilir.

  2. State tutuyorsa, global paylaşım kaynaklı hatalara açık olur.

  3. Test senaryolarında izole edilmesi zordur.

Ne Zaman Kaçınmalıyız?

  1. İçerisinde kullanıcıya veya request'e özel veri tutuyorsan

  2. EF Core DbContext gibi disposable objeler içeriyorsa

  3. Çok fazla state varsa ve değişiyorsa

​Scoped Service

​services.AddScoped<IMyService, MyService>();

Kullanım Senaryoları

  1. EF Core DbContext

  2. Unit of Work pattern

  3. Request’e bağlı işlem yapan servisler

  4. Kullanıcıya veya işleme özel state tutan sınıflar

Avantajlar

  1. Request başına tutarlı veri yönetimi

  2. En ideal state izolasyonu

  3. Web uygulamaları için varsayılan en sağlıklı yaklaşım

Riskler

  1. Background task veya Singleton içinde Scoped servis kullanılırsa sorun olabilir.

  2. Request-scope dışında referans alırsan “ObjectDisposedException” hatası alınabilir.

Ne Zaman Kaçınmalıyız?

  1. Singleton içinden scoped servis istemek
    (Bu, .NET Core’un en sık karşılaşılan anti-pattern’lerinden biridir.)

Transient Services

services.AddTransient<IMyService, MyService>();​

Kullanım Senaryoları

  1. Hafif ve stateless bileşenler

  2. Hizmet çağrılarının her defasında yeni oluşması gereken servisler

  3. Kısa ömürlü operasyon class’ları

Avantajlar

  1. State karışıklığı olmaz, her kullanımda sıfırdan başlar

  2. Deadlock ve concurrency riskleri daha düşüktür

Riskler

  1. Çok sık oluşturulan ağır sınıflarda performans kaybı

  2. Gereksiz GC (Garbage Collector) yükü

Ne Zaman Kaçınmalıyız?

  1. İçinde ağır kaynaklar veya bağlantılar varsa

  2. Sık çağrılan business logic bloklarında yoğun yük oluşturuyorsa

EF Core DbContext İçin Hangi Lifetime Doğru?

DbContext’in Singleton veya Transient olması hem thread yönetimini, hem transaction yapısını bozar. Microsoft tarafından resmi olarak Scoped önerilir.

Karar Verme Matrisi

Soru
Evet Hayır  
Servis state tutuyor mu?
Scoped
Transient
Request’e özel veri mi işliyor?
Scoped
Transient
Uygulama boyunca tek bir kez kullanılmalı mı?
Singleton
Scoped/Transient
Ağır bir sınıf mı?
Singleton/Scoped
Transient
Thread-safe mi?
Singleton olabilir
Scoped/Transient daha güvenli

Örnek Kod: Üç Lifetime'ın Uygulanışı

public void ConfigureServices(IServiceCollection services)
{
    // Her talepte yaratılır
    services.AddTransient<IEmailSender, EmailSender>();

    // Her request'te tek örnek
    services.AddScoped<IOrderService, OrderService>();

    // Uygulama süresince tek örnek
    services.AddSingleton<ICacheProvider, MemoryCacheProvider>();
}

Sonuç

.NET Core’da service lifetime seçimi, doğru mimariyi kurmanın temel adımlarından biridir. Doğru seçilmemiş bir yaşam döngüsü; performans sorunlarından veri tutarsızlıklarına kadar çok katmanlı problemlere yol açabilir.

Özetle:

  1. Singleton: Evrensel, thread-safe, state taşımayan servisler için

  2. Scoped: Request odaklı, DbContext gibi stateful servisler için

  3. Transient: Hafif, stateless, her kullanımda yenilenmesi gereken servisler için

Doğru lifetime = daha hızlı, daha temiz, daha güvenli bir .NET Core uygulaması.

Diğer Bloglarımda Görüşmek Üzere, 👋