Penggunaan Dependency Injection cukup penting dalam development aplikasi Android, karena selain membuat kode menjadi lebih clean code dan testable, juga membuat performa aplikasi jadi lebih baik.
Google merekomendasikan Dependency Injection Dagger, namun Dagger terkadang masih susah dipelajari untuk pemula dan terkadang mudah error karena memerlukan class yang digenerate oleh dagger. ada satu library Dependency Injection yang bisa mengatasi hal tersebut, library itu adalah Koin. Koin adalah Library yang Ringan dan Pragmatic. Koin dibuat dan digunakan di Kotlin. Koin tidak menggunakan class yang digenerate jadi meminimalisir error.
sekarang kita coba Praktekkan penggunaan KOIN pada Android.
langkah pertama Install Library untuk KOIN, tambahkan repositories mavenCentral (jika belum ditambahkan)
repositories {
mavenCentral()
}
lalu tambahkan library KOIN di build.gradle (app)
implementation "io.insert-koin:koin-core:$koin_version"
setelah terinstall. kita bisa langsung membuat module nya.
misal kita punya class Repository yang seperti ini :
class UserRepository (apiService:ApiService, appDatabase:AppDatabase) {
....
}
disitu kita perhatikan UserRepository meng inject class ApiService dan AppDatabase di Constructornya.
sekarang kita coba buat module nya, bikin satu file kotlin baru (untuk nama file terserah kalian), di dalam file tersebut buat satu variabel module seperti berikut :
val appModule = module {
single { ApiService.getService() }
single { AppDatabase.getDatabase(get()) }
}
val repositoryModule = module {
factory { UserRepository(get(), get()) }
}
disitu kita langsung membuat variabel tanpa perlu dimasukkan di dalam class.
kita membuat dua module yaitu appModule dan repositoryModule. dalam membuat module kita bungkus dengan kode module { } dan didalamnya kita inisialisasi class yang akan menjadi dependency dari class lain.
disitu kita meng inisialisasi class ApiService dan AppDatabase yang dibungkus dengan single { }, yang berarti kita membuat class ApiService dan AppDatabase menjadi Singleton (class tetap memiliki instance yang sama meskipun di inisialisasi berkali kali) sehingga lebih hemat memory, selain single { } kita juga bisa menggunakan factory { } yang dipergunakan untuk class yang bisa di . method getDatabase pada AppDatabase membutuhkan parameter Context, maka kita gunakan method get() untuk mendapatkan context. fungsi dari method get() ini adalah untuk mendapatkan class yang sudah di inisialisasi di module secara otomatis sesuai dengan type nya.
pada repositoryModule kita inisialisasi UserRepository dan langsung meng inject ApiService dan AppDatabase ke dalam parameter. kita bisa menginject class dari module lain.
Jika kita menggunakan ViewModel kita perlu membuat module khusus untuk ViewModel
misal kita punya ViewModel seperti berikut :
class UserViewModel(userRepo : UserRepository) : ViewModel() {
....
}
maka module nya adalah seperti berikut :
val viewModelModule = module {
viewModel { UserViewModel(get()) }
}
jika viewModel maka inisialisasinya dibungkus dengan viewModel { }
dan untuk memakai ViewModel nya di Activity atau Fragment, kita tinggal menggunakan by viewModel() seperti pada contoh berikut :
class MainActivity : AppCompatActivity {
private val userVM : UserViewModel by viewModel()
override fun onCreate(){
....
}
}
cukup mudah bukan ? sekarang bagaimana caranya melakukan inject ke variabel langsung. kita tinggal menggunakan by inject() seperti berikut.
semisal kita sudah meng inisialisasi SharedPreferences di module dan kita mau menggunakannya di class MainActivity.
class MainActivity : AppCompatActivity {
private val userVM : UserViewModel by viewModel()
private val prefs : SharedPreferences by inject()
override fun onCreate() {
....
}
}
maka viewmodel dan sharedpref bisa digunakan seperti biasa.
sekarang tinggal kita inisialisasi KOIN nya di class Application. buat satu class baru yang meng extends Application(). lalu lakukan inisalisasi KOIN
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidLogger()
androidContext(this@MyApplication)
modules(appModule, repositoryModule, viewModelModule)
}
}
}
kita inisialisasi koin dengan method startKoin { }. pada baris pertama androidLogger() untuk menampilkan log Dependency Injection, pada baris kedua kita inject Context (tadi kita memakai context untuk parameter di AppDatabase), lalu pada baris ketiga kita masukkan module-module yang kita pakai.
setelah itu edit AndroidManifest. tambahkan android:name di tag Application dengan isi class Application tempat kita meng inisialisasi koin
<application
android:name=".MyApplication"
android:allowBackup="true"
.... />
selesai sudah kita menerapkan Dependency Injection Koin di Kode kita.