Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dagger Hilt : Dependency Injection in Action - BDD 2020

Dagger Hilt : Dependency Injection in Action - BDD 2020

1fe3e1b3343b555b0a195180607fbd6a?s=128

Ahmad Arif Faizin

July 18, 2020
Tweet

Transcript

  1. Replace Me! (Bisa ditambahkan dengan image yang relevan) Dagger Hilt

    : Dependency Injection in Action Ahmad Arif Faizin - Dicoding Indonesia
  2. Dependency ??? Class B dikatakan dependency dari class A apabila

    Class A menggunakan fungsi yang ada di dalam Class B. Sehingga A tergantung pada B
  3. 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
  4. 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 ?
  5. 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)
  6. 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
  7. Dependency Injection Library Replace Me! (Bisa ditambahkan dengan image yang

    relevan)
  8. 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.
  9. Why Dagger Hilt?

  10. None
  11. 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() } }
  12. Lokasi inisialisi Engine

  13. 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" }
  14. 1. Create Module @Module @InstallIn(ApplicationComponent::class) class AppModule { @Provides fun

    provideEngine(): Engine = Engine() } Nama fungsi bebas Tidak berpengaruh Object yang di-provide
  15. Component

  16. 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>
  17. 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() } }
  18. Injection di Constructor class Car @Inject constructor(private val engine: Engine)

    { fun start() { engine.start() } }
  19. 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() } }
  20. Bagaimana jika butuh Context? @Module @InstallIn(ApplicationComponent::class) class AppModule { @Provides

    fun provideEngine(@ApplicationContext context: Context): Engine = Engine(context) }
  21. 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) }
  22. ✔ 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
  23. ✔ Inject WorkManager class ExampleWorker @WorkerInject constructor( @Assisted appContext: Context,

    @Assisted workerParams: WorkerParameters, workerDependency: WorkerDependency ) : Worker(appContext, workerParams) { ... } + Tanpa WorkerFactory + Tanpa membuat assisted inject manual
  24. Survey & Download sample project s.id/simple-hilt

  25. 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.
  26. 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
  27. Coming Soon ... Replace Me! (Bisa ditambahkan dengan image yang

    relevan)
  28. Contact: Ahmad Arif Faizin arif@dicoding.com medium.com/@arifaizin Replace Me! (Bisa ditambahkan

    dengan image yang relevan)