Share
Embed
Dagger Hilt : Dependency Injection in Action - BDD 2020
Ahmad Arif Faizin
July 18, 2020
Transcript
28 slides
-
Replace Me! (Bisa ditambahkan dengan image yang relevan) Dagger Hilt
: Dependency Injection in Action Ahmad Arif Faizin - Dicoding Indonesia -
Dependency ??? Class B dikatakan dependency dari class A apabila
Class A menggunakan fungsi yang ada di dalam Class B. Sehingga A tergantung pada B -
Contoh Dependency class Engine { fun start() { println("Engine started....")
} } class Car { private val engine = Engine() fun start() { engine.start() } } fun main() { val car = Car() car.start() } - Class Car dan Engine saling terhubung erat (tightly coupled). Sehingga ketika ingin membuat Car dengan Engine yang berbeda, Anda harus membuat Class Car baru lagi. - Membuat unit testing menjadi lebih sulit. Karena menggunakan real object Engine yang asli, bukan simulasi. Dependency Injection solusinya -
Dependency Injection ??? Mengeluarkan Class Engine dari Class Car dan
menyuntikkannya ke dalam Class Car. + Tidak saling terikat (loosely coupled), sehingga mesin mudah diubah-ubah (ease to refactor) + Mesin bisa digunakan di mobil lain (reusability) + Mobil mudah dites dengan simulasi mesin (ease of testing with mock) Bagaimana caranya ? -
1. Manual Dependency Injection • Constructor Injection class Car(private val
engine: Engine) { fun start() { engine.start() } } fun main() { val engine = Engine() val car = Car(engine) car.start() } • Field Injection class Car { lateinit var engine: Engine fun start() { engine.start() } } fun main() { val car = Car() val engine = Engine() car.engine = engine car.start() } penulisan untuk inisialisasi object berkali-kali bisa menyebabkan kesalahan (error-prone) -
2. Automated Dependency Injection + Menghindari kemungkinan terjadinya kesalahan saat
setiap kali membuat object (error-prone) + Menghindari penulisan kode yang berulang-ulang yang menyebabkan boilerplate + Menghindari pengaturan lifecycle dan scope secara manual yang bisa menyebabkan memory leaks -
Dagger Hilt • Hilt merupakan library Jetpack terbaru yang direkomendasikan
dalam dependency injection. • Dibuat di atas Dagger yang sudah teruji dan sangat kokoh (robust). 74% dari Aplikasi Top 10K menggunakan Dagger. • Bedanya yaitu proses yang lebih simpel dan lebih mudah dipelajari. -
Perbedaan Manual DI dengan Dagger Hilt • Before class MainActivity
: AppCompatActivity() { lateinit var engine: Engine override fun onCreate(...) { ... engine = Engine() val car = Car(engine) car.start() } } • After @AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject lateinit var engine: Engine override fun onCreate(...) { ... val car = Car(engine) car.start() } } -
0. Add dependencies • Build.gradle (project) buildscript { ... dependencies
{ classpath "com.android.tools.build:gradle:4.0.0" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version" } } • Build.gradle (module) apply plugin: 'dagger.hilt.android.plugin' dependencies { ... implementation "com.google.dagger:hilt-android:$hilt_version" kapt "com.google.dagger:hilt-android-compiler:$hilt_version" } -
1. Create Module @Module @InstallIn(ApplicationComponent::class) class AppModule { @Provides fun
provideEngine(): Engine = Engine() } Nama fungsi bebas Tidak berpengaruh Object yang di-provide -
2. Init to Application @HiltAndroidApp open class MyApplication : Application()
{ ... } AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest ...> <application android:name=".MyApplication" ... </application> </manifest> -
3. Start Injection! @AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject
lateinit var engine: Engine override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val car = Car(engine) car.start() } } -
Injection di Constructor class Car @Inject constructor(private val engine: Engine)
{ fun start() { engine.start() } } -
Diff setelah Injection di Constructor • Before @AndroidEntryPoint class MainActivity
: AppCompatActivity() { @Inject lateinit var engine: Engine override fun onCreate(...) { ... val car = Car(engine) car.start() } } • After @AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject lateinit var car: Car override fun onCreate(...) { ... car.start() } } -
Bagaimana jika butuh Context? @Module @InstallIn(ApplicationComponent::class) class AppModule { @Provides
fun provideEngine(@ApplicationContext context: Context): Engine = Engine(context) } -
Bagaimana membuat Singleton? @Singleton class Car @Inject constructor(private val engine:
Engine) { fun start() { engine.start() } } ...... @Module @InstallIn(ApplicationComponent::class) class AppModule { @Singleton @Provides fun provideEngine(@ApplicationContext context: Context): Engine = Engine(context) } -
✔ Inject ViewModel class HomeViewModel @ViewModelInject constructor(...) : ViewModel() {
... } ...... @AndroidEntryPoint class HomeFragment : Fragment() { private val viewModel: HomeViewModel by viewModels() } + Tanpa ViewModelFactory + Tanpa menggunakan Multi-binding seperti pada Dagger -
✔ Inject WorkManager class ExampleWorker @WorkerInject constructor( @Assisted appContext: Context,
@Assisted workerParams: WorkerParameters, workerDependency: WorkerDependency ) : Worker(appContext, workerParams) { ... } + Tanpa WorkerFactory + Tanpa membuat assisted inject manual -
Kesimpulan ✓ Dependency Injection membuat kode Anda tidak saling terikat,
sehingga menjadi mudah dimodifikasi dan mudah dites. ✓ Automated Dependency Injection digunakan untuk mengurangi boilerplate, error-prone dan memory leak. ✓ Hilt memudahkan Anda dalam membuat Dependency Injection dengan step “ritual” yang lebih ringkas dengan adanya pre-defined scope. ✓ Hilt sudah terintegrasi dengan library Jetpack yang lain sehingga bisa mengurangi jumlah kode. -
Referensi • https://developer.android.com/training/dependency-injection/hilt-android • https://codelabs.developers.google.com/codelabs/android-dagger-to-hilt • https://speakerdeck.com/sidiqpermana/playing-with-hilt-di • #Android11 :
What's new in Android Jetpack • A quick intro to Dependency Injection: what it is, and when to use it -
Contact: Ahmad Arif Faizin [email protected] medium.com/@arifaizin Replace Me! (Bisa ditambahkan
dengan image yang relevan)