Rankinio jungimo skausmas ir DI
Prisimink 5 pamokos pabaigą. Kad meniu užsikrautų, viską surišom rankomis:
// LESSON 5 — grandinė, sudėta ranka
object Network {
private val retrofit = Retrofit.Builder()...build()
val api: PicaApi = retrofit.create(PicaApi::class.java)
}
val vm = viewModel { MenuViewModel(MenuRepository(Network.api)) }
Veikia — bet pažvelk atidžiau. Kiekvienas ekranas, kuriam reikia MenuViewModel, turi žinoti, kaip pastatyti visą grandinę: Network.api → MenuRepository → MenuViewModel. Kai 8–9 pamokose atsiras TokenStorage, AuthInterceptor, OrderRepository, ta grandinė išaugs ir kiekvienas naujas ekranas kartos tą patį montavimą. Pakeitus vieną gabalą (pvz., baseUrl) — teks lakstyti po visą kodą.
Priklausomybių injekcija (DI) apverčia tai. Klasė nebekuria savo priklausomybių — ji jas priima konstruktoriuje (class MenuViewModel(private val repo: MenuRepository) — kaip jau darėm). O kas jas sukuria? Vienas centrinis „receptų sąrašas" — DI konteineris.
Koin — lengvas DI konteineris Kotlinui. Trys pagrindiniai receptai:
single { ... }— sukurk vieną egzempliorių ir dalink jį visiems (pvz.,Retrofit,PicaApi, repozitorijos).factory { ... }— sukurk naują egzempliorių kiekvienam prašymui.viewModel { ... }— kaipfactory, bet susieta su ekrano gyvavimo ciklu (Android ViewModel).get()— „paklausk Koino, kas čia turi būti" — Koin pats suranda ir sukuria priklausomybę.
Receptai gyvena moduliuose (val coreModule = module { ... }), o programa juos užregistruoja paleisdama startKoin { }.
Šioje pamokoje object Network iš 5 pamokos išnyks: jį pakeis coreModule, o ekranai priklausomybes gaus per koinViewModel().