Koin — kod yaradılması, refleksiya və annotasiyalar olmadan işləyən Kotlin üçün DI freymvorkudur. Kitabxana modulları təsvir etmək üçün DSL-dən istifadə edir və asılılıqları Android, Ktor və Multiplatform dəstəyi ilə yüngül konteyner vasitəsilə yerləşdirir. Koin-in rəsmi sənədlərinə görə, freymvork modullar, skoplər və minimal boilerplate ilə Jetpack Compose üçün daxili dəstək təmin edir.
Başlıca məqamlar
Koin — təmiz dildə, refleksiya, annotasiya və ya kod yaradılması olmadan yazılmış Kotlin üçün DI freymvorkudur. Kompilyasiya mərhələsində annotasiya prosessoru və kod yaradılması tələb edən Dagger Hilt-dən fərqli olaraq, Koin yalnız runtime-da, modulları təsvir etmək üçün yüngül DSL istifadə edərək işləyir.
Koin-in əsas ideyası — mürəkkəb asılılıq qrafşları və komponent ağacları konsepsiyalarını öyrənmək məcburiyyəti olmadan asılılıqların qeydiyyatı və həlli üçün sadə API təmin etməkdir. Tərtibatçı konteyner üçün hansı siniflərin mövcud olduğunu təsvir edir, Koin isə onları konstruktor və ya by inject gecikmiş delegatları vasitəsilə avtomatik yerləşdirir. Freymvork Kotlin Multiplatform ilə tam uyğumdur ki, bu da Android, iOS və server tərəfində vahid DI yanaşmasından istifadə etməyə imkan verir.
Kotlin Developers Community sorğusuna (2025) görə, Koin kommersiya Android layihələrinin 31%-də istifadə olunur, populyarlıq baxımından yalnız Hilt-dən (47%) geri qalır. Seçimin əsas səbəbi — konfiqurasiyanın sadəliyi və kod yaratmağa ehtiyac olmaması, bu da layihənin qurulmasını sürətləndirir.
Tərtibatın sürətli başlamasının vacib olduğu orta və böyük layihələr üçün və ya Hilt-in memarlıq səbəblərdən mövcud olmadığı Kotlin Multiplatform həlləri üçün Koin-i seçin.
Koin refleksiya və kod yaradılmasından istifadə etmir — bütün qeydiyyatlar reified tipli inline funksiyalara əsaslanır ki, onlar kompilyasiya mərhələsində funksiya bədəninə konkret tipi yerləşdirirlər. Bu, Koin-i son APK ölçüsünə görə ən yüngül DI freymvorklarından birinə çevirir: Koin-in əlavə edilməsi tətbiqin ölçüsünü cəmi 100–150 KB artırır, halbuki Dagger Hilt yaradılan kod hesabına təxminən 500 KB əlavə edir.
Koin konteyneri konfiqurasiya ilə lambda qəbul edən startKoin funksiyası vasitəsilə işə salınır. Bu lambdanın içərisində qeydiyyatlarla modullar təsvir olunur — DI məntiqinin əsas tikinti bloku.
startKoin funksiyası GlobalContext vasitısilə tətbiqin istənilən nöqtəsindən əlçatan qlobal konteyner yaradır, lakin çoxmodullu layihələrdə izolyasiya olunmuş konteynerlər yaratmaq üçün KoinApplication istifadə etmək tövsiyə olunur. Android-dé işə salma üçün avtomatik olaraq Application həyat dövrünə bağlanan AndroidContext istifadə olunur. Modullar Module nüsxələrinin siyahısını qəbul edən modules parametri vasitəsilə qeydiyyatdan keçirilir.
val networkModule = module {
single {
OkHttpClient()
}
single {
Retrofit.Builder()
.baseUrl("https://api.example.com")
.build()
}
}
startKoin {
modules(networkModule)
}
Hər modul single (sinqlton) və ya factory (yeni nüsxə) vasitəsilə təriflər ehtiva edir. Təriflər get() vasitəsilə digər qeydiyyatdan keçmiş asılılıqlara istinad edə bilər ki, bu da tipləri açıq göstərmədən və boilerplate kodu olmadan yerləşdirmə qrafşı yaradır.
Koin kontekstdən tip çıxarmaq üçün reified parametrləri olan inline funksiyalardan fəal istifadə edir. Bu, sinfi açıq göstərmədən qeydiyyat yazmağa imkan verir: single { MyService() } avtomatik olaraq lambdanın qaytardığı dəyərə görə tipi müəyyən edir.
Dagger-dən fərqli olaraq, Koin asılılıq qrafşını kompilyasiya mərhələsində yoxlamır — bütün səhvlər həll olunmamış asılılığa ilk müraciətdə runtime-da aşkarlanır. Bu, kodu əhəmiyyətlı dərəcədə sadələşdirən və qurulmanı sürətləndirən, lakin DI konfiqurasiyasının test əhatəsini tələb edən bir kompromisdir. Bir çox komanda kompilyasiya zamanı yoxlamalarının olmamasına baxmayaraq, Koin-i məhz inkişaf sürəti və sadəliyi üçün seçir.
Koin 3.5 versiyasında Koin Annotations plaqini vasitəsilə kompilyasiya mərhələsində qrafın eksperimental yoxlaması peyda oldu. Tərtibatçı @Module və @KoinComponent annotasiyalarını əlavə edir, plaqin isə qurulma zamanı işləyən doğrulama kodu yaradır. Lakin Koin-in əsas üstünlüyü — kod yaradılmasının olmaması — bu rejimdə itir, ona görə də əksər komandalar testlər vasitəsilə runtime yoxlamaları ilə klassik DSL yanaşmasından istifadə etməyə davam edir.
Koin asılılıqların yerləşdirilməsi üçün bir neçe üsul təqdim edir: by inject(), get() və konstruktor vasitəsilə birbaşa ötürülmə. Ösulun seçimi istifadə kontekstindən asılıdır.
by inject delegatı — ViewModel və Android fraqmentlərində ən geniş yayılmış yerləşdirmə üsuludur. Asılılıq gecikmiş şəkildə — yalnız xassəyə ilk müraciətdə işə salınır. Bu, dərhal lazım olmaya biləcək resurs tutumlu servislər üçün səmərəlidir.
class MainViewModel : ViewModel() {
private val repository: UserRepository by inject()
fun loadUsers() {
repository.fetchAll()
}
}
get funksiyası asılılığın nüsxəsini dərhal qaytarır. Qeydiyyat zamanı fabrik lambdalarının içərisində və ya asılılığın gecikmiş işə salma olmadan sinxron kontekstdə lazım olduğu hallarda istifadə olunur. by inject()-ən fərqli olaraq, get() gecikmiş yükləməni dəstəkləmir və çağrış anında konteynerin artıq işə salınmasını tələb edir.
Scope Koin-də — asılılıqların ömür dövrünü Activity, Fragment və ya istifadəçi sessiyası kimi müəyyən bir komponentə bağlamaq mexanizmidir. Bu, Android tətbiqlərində yaddaşı idarə etmək üçün əsas funksionallıqdır.
Modul daxilində scope funksiyası bağlı komponent yaşadığı müddət yaşayan skop yaradır. Skopda qeydiyyatdan keçmiş bütün asılılıqlar bağlandıqda məhv olur ki, bu da yaddaş sızıntılarının qarşısını alır.
val userScope = module {
scope<UserSession> {
scoped {
UserRepository(get())
}
scoped {
SessionManager(get())
}
}
}
scoped funksiyası yalnız skop daxilində mövcud olacaq asılılığı qeydiyyatdan keçirir. Skop bağlandıqda bütün scoped obyektlər zibil yığıcı üçün əlçatmaz olur.
single — gecikmiş işə salma ilə bütün tətbiq üçün vahid nüsxənin qeydiyyatı. Vəzifəsiz servislər üçün istifadə olunur: şəbəkə müştəriləri, keşlər, loggerlər.
factory — hər get() çağrışı yeni nüsxə yaradır. Hər müraciətdə təzə nüsxənin vacib olduğu ViewModel, repozitoriyalar və vəziyyətli obyektlər üçün tətbiq olunur.
Koin-in Android layihəsinə inteqrasiyı minimaldır: build.gradle-ə asılılıq əlavə etmək və Application.onCreate-də startKoin çağırmaq kifayətdir. Koin Jetpack Compose, Navigation və WorkManager ilə inteqrasiya üçün modullar təmin edir ki, bu da onu Hilt-ə tam hüquqlu alternativ edir.
Xüsusi koin-android-compose kitabxanası koinViewModel() və koinInject() funksiyaları vasitəsilə birbaşa Composable funksiyalarında asılılıqları yerləşdirməyə imkan verir. Bu, konteyneri hər ekranın parametrləri vasitəsilə ötürmək ehtiyacını aradan qaldırır və həyat dövrü ilə avtomatik əlaqə sayəsində ViewModel kodunu daha təmiz edir.
Google I/O 2024-ə görə, Jetpack Compose yeni Android layihələri üçün əsas freymvorka çevrildi. Koin əlavə konfiqurasiya olmadan Compose-ın doğma dəstəyini təmin edir, koinViewModel() vasitəsilə skoplərı ViewModel həyat dövrü ilə avtomatik əlaqələndirir və coroutine kontekstini nəzərə alır.
Test etmək üçün Koin test modulları ilə izolyasiya olunmuş konteyner yaradan və test bitdikdən sonra onu avtomatik bağlayan koinTest və koinTestRule funksiyalarını təqdim edir. Bu, testlərin izolyasiyasını təmin edir və test halları arasında vəziyyət sızıntılarının qarşısını alır.
Koin-in Jetpack Navigation ilə inteqrasiyası koin-androidx-navigation modulu vasitəsilə həyata keçirilir. Hər ekranın ViewModel-i avtomatik olaraq by viewModel() vasitəsilə asılılıqları alır və ekranın döndərilməsi zamanı vəziyyəti qorumaq və tətbiq kiçildildikdən sonra bərpa etmək üçün SavedStateHandle ötürülür.
ViewModel-in Koin ilə vahid testi üçün koin-test-junit5 və ya koin-test-junit4 kitabxanasından koinTestRule istifadə olunur. Qayda hər testdən əvvəl test modulları ilə izolyasiya olunmuş konteyner yaradır və bitdikdən sonra onu avtomatik bağlayır, test halları arasında vəziyyət sızıntılarının qarşısını alır. Həqiqi asılılıqlar MockK vasitəsilə mock-larla əvəz olunur: single
Koin 3.x-in əsas imkanlarından biri Kotlin-də server tətbiqləri yaratmaq üçün Ktor və desktop tətbiqləri üçün Compose Multiplatform dəstəyidir. Bu, Koin-i yerləşdirmə paradigm dəyişmədən Kotlin-in hər üç platformasını əhatə edən yeganə DI freymvorku edir. koin-ktor modulu Application blokunda install(Koin) vasitəsilə asılılıqları qeydiyyatdan keçirməyə və Android-də olduğu kimi by inject() vasitəsilə servisləri marşrutlara yerləşdirməyə imkan verir. Bu, Koin-i mobil müştəridən server backendinə qədər istənilən memarlıqlı Kotlin layihələri üçün universal DI həllinə çevirir.
Koin-in Jetpack Navigation ilə koin-androidx-navigation modulu vasitəsilə inteqrasiyası hər ekran üçün əl ilə ViewModelProvider.Factory yaratmaq ehtiyacını aradan qaldırır. Çoxmodullu layihələr üçün Koin loadKoinModules vasitƏsilƏ modulların gecikmiş yüklənməsini dəstəkləyir ki, bu da hər bir funksiya modulunun DI konfiqurasiyasını müstəqil qoşmağa imkan verir.
Tez-tez verilən suallar
Koin kod yaradılması və annotasiyalar olmadan runtime-da işləyir, bu da qurulmanı sürətləndirir, lakin asılılıq qrafşını kompilyasiya mərhələsində yoxlamır. Hilt kompilyasiya zamanı kod yaradır və DI səhvlərini daha tez tutur, lakin mürəkkəb konfiqurasiya tələb edir və qurulmanı yavaşlatır.
Bəli, Koin Kotlin Multiplatform-u tam dəstəkləyir. koin-core kitabxanası bütün Kotlin platformalarında işləyir, koin-android və koin-compose isə müvafiq olaraq Android və iOS üçün platforma-spesifik imkanlar əlavə edir.
Tsiklik asılılıqlar runtime-da StackOverflowError-a səbəb olur. Koin onları avtomatik aşkarlamır. Həll yolu — memarlığın refaktorinqi: ümumi interfeysin ayrılması, Listener/Observer nümunəsinin istifadəsi və ya gecikmiş işə salma ilə fabrik vasitəsilə dövrün qırılması.
Android-də skoplər AndroidScope vasitəsilə Activity və ya Fragment-in həyat dövrünə bağlana bilər. Komponent məhv olduqda Koin müvafiq skopu avtomatik bağlayır. İstifadəçi skoplərində (istifadəçi sessiyası) bağlanma scope.close çağrışı ilə əl ilə həyata keçirilir.
koin-test modulundan koinTest funksiyasından istifadə edin. O, test modulları ilə izolyasiya olunmuş konteyner yaradır və testdən sonra avtomatik bağlanır. Həqiqi asılılıqlar Mockito və ya MockK ilə modul vasitəsilə mock-larla əvəz olunur.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun