Koin — nedir, Dependency Injection ilkeleri ve nasıl çalışır

Yazar: IT Sectr Yayınlanma: 2026-05-04 Okuma süresi: 8 dk

Koin, kod üretimi, yansıma veya ek açıklama olmadan çalışan bir Kotlin DI framework'üdür. Kütüphane, modülleri tanımlamak için DSL kullanır ve Android, Ktor ve Multiplatform desteğiyle hafif bir konteyner aracılığıyla bağımlılıkları enjekte eder. Resmi Koin dokümantasyonuna göre, framework, minimum boilerplate ile modüller, kapsamlar ve Jetpack Compose için yerleşik destek sağlar.

Önemli Noktalar

  • Koin, yansıma veya kod üretimi olmadan DSL kullanan bir Kotlin DI framework'üdür.
  • Modül, single ve factory fonksiyonları aracılığıyla bağımlılık kayıtlarının mantıksal bir gruplamasıdır.
  • single, örneği bir kez oluşturulan bir singleton kaydeder.
  • factory, her istekte yeni bir örnek oluşturur.
  • Scope, bağımlılığın yaşam süresini bir Activity gibi bir bileşene bağlayan mekanizmadır.

Koin nedir ve farkı nedir

Koin, yansıma, ek açıklama veya kod üretimi kullanmadan saf dille yazılmış bir Kotlin DI framework'üdür. Derleme zamanında ek açıklama işlemcisi ve kod üretimi gerektiren Dagger Hilt'in aksine Koin, modülleri tanımlamak için hafif bir DSL kullanarak tamamen çalışma zamanında çalışır.

Koin'in ana fikri, karmaşık bağımlılık grafiği ve bileşen ağacı kavramlarını öğrenmeye gerek kalmadan bağımlılıkları kaydetmek ve çözmek için basit bir API sağlamaktır. Geliştirici, konteyner için hangi sınıfların kullanılabilir olduğunu tanımlar ve Koin, bunları kurucu veya by inject yoluyla tembel temsilciler aracılığıyla otomatik olarak enjekte eder. Framework, Kotlin Multiplatform ile tam uyumludur ve Android, iOS ve sunucu tarafında birleşik bir DI yaklaşımına olanak tanır.

Kotlin Geliştirici Topluluğu anketine (2025) göre Koin, ticari Android projelerinin %31'inde kullanılmakta olup yalnızca Hilt'in (%47) ardından ikinci sıradadır. Seçilmesinin ana nedeni, kurulum kolaylığı ve proje derlemesini hızlandıran kod üretimi gereksiniminin olmamasıdır.

Hızlı geliştirme başlatmanın önemli olduğu orta ve büyük projeler için veya mimari nedenlerle Hilt'in kullanılamadığı Kotlin Multiplatform çözümleri için Koin'i seçin.

Koin, yansıma veya kod üretimi kullanmaz — tüm kayıtlar, derleme zamanında işlev gövdesine somut türü yerleştiren reified türlere sahip inline işlevler üzerine kurulmuştur. Bu, Koin'i nihai APK boyutu açısından en hafif DI framework'lerinden biri yapar: Koin eklemek, uygulama boyutunu yalnızca 100-150 KB artırırken, Dagger Hilt üretilen kod nedeniyle yaklaşık 500 KB ekler.

Koin konteyner ve DSL nasıl çalışır

Koin konteyneri, yapılandırmayla bir lambda alan startKoin işlevi aracılığıyla başlatılır. Bu lambda içinde, DI mantığının ana yapı taşı olan kayıtlı modüller tanımlanır.

startKoin ve modüller

startKoin işlevi, GlobalContext aracılığıyla uygulamanın her yerinden erişilebilen küresel bir konteyner oluşturur, ancak çok modüllü projelerde izole konteynerler oluşturmak için KoinApplication kullanılması önerilir. Android'de, başlatma için otomatik olarak Application yaşam döngüsüne bağlanan AndroidContext kullanılır. Modüller, Module örneklerinin bir listesini alan modules parametresi aracılığıyla kaydedilir.

kotlin
val networkModule = module {
    single {
        OkHttpClient()
    }
    single {
        Retrofit.Builder()
            .baseUrl("https://api.example.com")
            .build()
    }
}

startKoin {
    modules(networkModule)
}

Her modül, single (singleton) veya factory (yeni örnek) aracılığıyla tanımlar içerir. Tanımlar, get() aracılığıyla diğer kayıtlı bağımlılıklara başvurabilir ve açık tür belirtimi ve boilerplate kodu olmadan bir enjeksiyon grafiği oluşturur.

DSL ve inline işlevler

Koin, bağlamdan tür çıkarımı için reified parametrelere sahip inline işlevleri aktif olarak kullanır. Bu, sınıfı açıkça belirtmeden kayıt yazmaya olanak tanır: single { MyService() }, lambda'nın dönüş değerinden türü otomatik olarak belirler.

Dagger'dan farklı olarak Koin, bağımlılık grafiğini derleme zamanında kontrol etmez — tüm hatalar, çözülmemiş bir bağımlılığa ilk erişimde çalışma zamanında tespit edilir. Bu, kodu önemli ölçüde basitleştiren ve derlemeleri hızlandıran ancak DI yapılandırmasının test kapsamını gerektiren bir ödünleşmedir. Birçok ekip, derleme zamanı kontrollerinin olmamasına rağmen, geliştirme hızı ve basitlik için Koin'i seçer.

Koin sürüm 3.5'te, Koin Annotations eklentisi aracılığıyla deneysel derleme zamanı grafik kontrolü ortaya çıktı. Geliştirici @Module ve @KoinComponent ek açıklamalarını ekler ve eklenti, derleme sırasında çalışan doğrulama kodu üretir. Ancak Koin'in ana avantajı — kod üretimi olmaması — bu modda kaybolur, bu nedenle çoğu ekip, testler aracılığıyla çalışma zamanı kontrolleriyle klasik DSL yaklaşımını kullanmaya devam eder.

Koin'de bağımlılık enjeksiyon yöntemleri

Koin, bağımlılıkları enjekte etmek için çeşitli yöntemler sunar: by inject(), get() ve doğrudan kurucu aktarımı. Seçim, kullanım bağlamına bağlıdır.

by inject() — tembel enjeksiyon

by inject temsilcisi, Android ViewModel ve fragment'larında en yaygın enjeksiyon yöntemidir. Bağımlılık, tembel olarak — yalnızca ilk özellik erişiminde başlatılır. Bu, hemen ihtiyaç duyulmayabilecek kaynak yoğun hizmetler için verimlidir.

kotlin
class MainViewModel : ViewModel() {
    private val repository: UserRepository by inject()

    fun loadUsers() {
        repository.fetchAll()
    }
}

get() — açık alma

get işlevi, bir bağımlılık örneğini hemen döndürür. Kayıt sırasında fabrika lambdaları içinde veya bağımlılığın tembel başlatma olmadan senkron bir bağlamda gerekli olduğunda kullanılır. by inject()'in aksine, get() tembel yüklemeyi desteklemez ve çağrı sırasında konteynerin zaten başlatılmış olmasını gerektirir.

Koin'de modüller ve kapsamlar

Koin'de kapsam, bağımlılık yaşam süresini bir Activity, Fragment veya özel oturum gibi belirli bir bileşene bağlama mekanizmasıdır. Bu, Android uygulamalarında bellek yönetimi için anahtar bir işlevdir.

scope — bir bileşene bağlama

Bir modül içindeki scope işlevi, bağlı bileşen yaşadığı sürece yaşayan bir kapsam oluşturur. Kapsamda kayıtlı tüm bağımlılıklar, kapsam kapatıldığında yok edilir ve bellek sızıntıları önlenir.

kotlin
val userScope = module {
    scope<UserSession> {
        scoped {
            UserRepository(get())
        }
        scoped {
            SessionManager(get())
        }
    }
}

scoped işlevi, yalnızca kapsam içinde var olacak bir bağımlılık kaydeder. Kapsam kapatıldığında, tüm scoped nesneler çöp toplayıcı için kullanılabilir hale gelir.

single vs factory

single, tembel başlatma ile tüm uygulama için tek bir örnek kaydeder. Durumsuz hizmetler için kullanılır: ağ istemcileri, önbellekler, günlükçüler.

factory, her get() çağrısında yeni bir örnek oluşturur. Her erişimde yeni bir örneğin önemli olduğu ViewModel, depolar ve durumlu nesneler için uygulanır.

Android projelerinde Koin

Koin'i bir Android projesine entegre etmek minimaldir: sadece build.gradle'a bir bağımlılık ekleyin ve Application.onCreate'da startKoin'i çağırın. Koin, Jetpack Compose, Navigation ve WorkManager ile entegrasyon için modüller sağlayarak Hilt'e tam bir alternatif haline gelir.

Özel koin-android-compose kütüphanesi, koinViewModel() ve koinInject() aracılığıyla doğrudan Composable işlevlerine bağımlılıkları enjekte etmeye olanak tanır. Bu, konteyneri her ekranın parametreleri aracılığıyla geçirme ihtiyacını ortadan kaldırır ve otomatik yaşam döngüsü bağlamasıyla ViewModel kodunu daha temiz hale getirir.

Google I/O 2024'e göre Jetpack Compose, yeni Android projeleri için birincil framework haline geldi. Koin, ek yapılandırma olmadan Compose için yerel destek sağlar ve coroutine bağlamını dikkate alarak koinViewModel() aracılığıyla kapsamları otomatik olarak ViewModel yaşam döngüsüne bağlar.

Test için Koin, test modülleriyle izole bir test konteyneri oluşturan ve test tamamlandıktan sonra otomatik olarak kapatan koinTest ve koinTestRule işlevlerini sağlar. Bu, test izolasyonunu garanti eder ve test durumları arasında durum sızıntılarını önler.

Koin'in Jetpack Navigation ile entegrasyonu, koin-androidx-navigation modülü aracılığıyla uygulanır. Her ekranın ViewModel'i, ekran döndürmede durumu korumak ve uygulama askıya alındıktan sonra kurtarmak için SavedStateHandle geçişiyle by viewModel() aracılığıyla otomatik olarak bağımlılıkları alır.

Koin ile ViewModel birim testi için, koin-test-junit5 veya koin-test-junit4 kütüphanesinden koinTestRule kullanılır. Kural, her testten önce test modülleriyle izole bir konteyner oluşturur ve tamamlandıktan sonra otomatik olarak kapatarak test durumları arasında durum sızıntılarını önler. Gerçek bağımlılıklar, MockK aracılığıyla mock'larla değiştirilir: single { mockk() } kayıtlarına sahip bir modül, ana modülü geçersiz kılar ve testteki ViewModel öngörülebilir bağımlılık davranışı alır.

Koin 3.x'in temel özelliklerinden biri, Kotlin'de sunucu uygulamaları oluşturmak için Ktor ve masaüstü uygulamalar için Compose Multiplatform desteğidir. Bu, Koin'i enjeksiyon paradigmasını değiştirmeden üç Kotlin platformunu da kapsayan tek DI framework'ü yapar. koin-ktor modülü, Application bloğunda install(Koin) aracılığıyla bağımlılıkları kaydetmeye ve Android'de olduğu gibi by inject() aracılığıyla yollara hizmet enjekte etmeye olanak tanır. Bu, Koin'i mobil istemciden sunucu arka ucuna kadar her mimarideki Kotlin projeleri için evrensel bir DI çözümü yapar.

koin-androidx-navigation modülü aracılığıyla Jetpack Navigation ile Koin entegrasyonu, her ekran için manuel olarak ViewModelProvider.Factory oluşturma ihtiyacını ortadan kaldırır. Çok modüllü projeler için Koin, loadKoinModules aracılığıyla tembel modül yüklemeyi destekler ve her özellik modülünün DI yapılandırmasını bağımsız olarak bağlamasına olanak tanır.

Sıkça Sorulan Sorular

Koin, Dagger Hilt'ten nasıl farklıdır?

Koin, kod üretimi veya ek açıklama olmadan çalışma zamanında çalışır, bu derlemeleri hızlandırır ancak bağımlılık grafiğini derleme zamanında kontrol etmez. Hilt, derleme zamanında kod üretir ve DI hatalarını daha erken yakalar, ancak karmaşık kurulum gerektirir ve derlemeyi yavaşlatır.

Koin, Kotlin Multiplatform'u destekliyor mu?

Evet, Koin Kotlin Multiplatform'u tamamen destekler. koin-core kütüphanesi tüm Kotlin platformlarında çalışırken, koin-android ve koin-compose sırasıyla Android ve iOS için platforma özel yetenekler ekler.

Koin'de döngüsel bağımlılıklar nasıl ele alınır?

Döngüsel bağımlılıklar, çalışma zamanında StackOverflowError'a yol açar. Koin bunları otomatik olarak algılamaz. Çözüm, mimari yeniden düzenlemedir: ortak bir arayüz çıkarma, Listener/Observer desenini kullanma veya ertelenmiş başlatma ile bir fabrika aracılığıyla döngüyü kırma.

Kapsamları manuel olarak kapatmam gerekir mi?

Android'de, kapsamlar AndroidScope aracılığıyla Activity veya Fragment yaşam döngüsüne bağlanabilir. Bileşen yok edildiğinde, Koin otomatik olarak ilgili kapsamı kapatır. Özel kapsamlarda (kullanıcı oturumu), kapatma scope.close çağrılarak manuel olarak yapılır.

Koin ile kod nasıl test edilir?

koin-test modülünden koinTest işlevini kullanın. Test modülleriyle izole bir konteyner oluşturur ve testten sonra otomatik olarak kapanır. Gerçek bağımlılıklar, Mockito veya MockK ile bir modül aracılığıyla mock'larla değiştirilir.

Özet

  • Koin, yansıma, ek açıklama veya kod üretimi olmadan DSL ile Kotlin için bir DI framework'üdür.
  • Modüller, kayıtları single (singleton) ve factory (yeni örnek) aracılığıyla gruplar.
  • startKoin, by inject() ve get() aracılığıyla erişilebilen küresel bir konteyner başlatır.
  • Kapsam, bağımlılık yaşam süresini Android bileşen yaşam döngüsüne bağlar.
  • Compose'da enjeksiyon, koinViewModel() ve koinInject() aracılığıyla yapılır.
  • Koin, Kotlin Multiplatform'u destekleyerek tüm platformlarda birleşik bir DI yaklaşımı sağlar.
  • DI hataları çalışma zamanında tespit edilir, bu nedenle yapılandırmanın test kapsamı zorunludur.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun