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

Hilt the DI ground running

Hilt the DI ground running

This talk was about Dependency Injection with Hilt at DevFest Egypt. First I explained the concept of Dependency Injection without libraries. Next, I showed how to incorporate Hilt into a new app and how to migrate an existing app.

Moyinoluwa Adeyemi

October 17, 2020

Transcript

78 slides
  1. What is Dependency Injection? “dependency injection is a technique in

    which an object receives other objects that it depends on” According to good ol’ wikipedia
  2. No Dependency Injection class RoboGardener { fun waterPlant() { val

    waterSource = WaterSource() waterSource.dispenseWater() } }
  3. Dependency Injection - Constructor class RoboGardener(private val waterSource: WaterSource) {

    fun waterPlant() { waterSource.dispenseWater() } } fun main() { val roboGardener = RoboGardener(CupOfWater()) roboGardener.waterPlant() }
  4. Dependency Injection - Setter class RoboGardener { lateinit var waterSource:

    WaterSource fun waterPlant() { waterSource.dispenseWater() } }
  5. Dependency Injection - Setter class RoboGardener { lateinit var waterSource:

    WaterSource fun waterPlant() { waterSource.dispenseWater() } } fun main() { val roboGardener = RoboGardener() roboGardener.waterSource = WateringCan() roboGardener.waterPlant() }
  6. Dependency Injection - Interface interface WaterSourceManager { fun provideWaterSource(waterSource: WaterSource)

    } class RoboGardener() : WaterSourceManager { private lateinit var waterSource: WaterSource override fun provideWaterSource(waterSource: WaterSource) { this.waterSource = waterSource } ...
  7. Dependency Injection - Interface interface WaterSourceManager { fun provideWaterSource(waterSource: WaterSource)

    } class RoboGardener() : WaterSourceManager { private lateinit var waterSource: WaterSource override fun provideWaterSource(waterSource: WaterSource) { this.waterSource = waterSource } fun waterPlant() { waterSource.dispenseWater() } } fun main() { val roboGardener = RoboGardener() roboGardener.provideWaterSource(Hose()) roboGardener.waterPlant() }
  8. Service Locators class RoboGardener { fun waterPlant() { val waterSource

    = CupOfWater() waterSource.dispenseWater() } }
  9. Dependency Injection - Dagger Dagger Code generation Steep learning curve

    For Java or Kotlin developers Useful for large projects
  10. @AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject lateinit var imageLoader:

    ImageLoader private val viewModel: HiltSampleViewModel by viewModels() ... @AndroidEntryPoint
  11. @AndroidEntryPoint @AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject lateinit var

    imageLoader: ImageLoader private val viewModel: HiltSampleViewModel by viewModels() ...
  12. Scoping - Unscoped bindings @Module @InstallIn(ApplicationComponent::class) abstract class AppModule {

    @Binds abstract fun bindImageLoader(imageLoader: GlideImageLoader): ImageLoader ...
  13. Scoping - Scoped bindings @Module @InstallIn(ApplicationComponent::class) abstract class AppModule {

    @Singleton @Binds abstract fun bindImageLoader(imageLoader: GlideImageLoader): ImageLoader ... ✅
  14. Scoping - Scoped bindings @Module @InstallIn(ApplicationComponent::class) abstract class AppModule {

    @ActivityRetainedScoped @Binds abstract fun bindImageLoader(imageLoader: GlideImageLoader): ImageLoader ... ❌
  15. Scoping - Predefined qualifiers class HiltSampleRepositoryImpl @Inject constructor( @ActivityContext private

    val context: Context, private val hiltSampleService: HiltSampleService ) : HiltSampleRepository {
  16. Multi-module apps - Feature modules “Hilt cannot process annotations in

    feature modules. You must use Dagger to perform dependency injection in your feature modules” Hilt + Dagger
  17. Multi-module apps - Feature modules 1. Install an Entry Point

    in the Application Component from the app module
  18. Multi-module apps - Feature modules 1. Install an Entry Point

    in the Application Component from the app module @EntryPoint @InstallIn(ApplicationComponent::class) interface ImageFeatureModule { fun imageLoader(): ImageLoader }
  19. Multi-module apps - Feature modules 2. In the feature module,

    create a regular dagger component @Component(dependencies = [ImageFeatureModule::class]) interface ImageFeatureComponent { fun inject(activity: ImageFeatureModuleActivity) @Component.Builder interface Builder { fun dependencies(imageFeatureModule: ImageFeatureModule): Builder fun build(): ImageFeatureComponent } }
  20. Multi-module apps - Feature modules 3. Inject the dependency in

    the feature module class ImageFeatureModuleActivity : AppCompatActivity() { @Inject lateinit var imageLoader: ImageLoader @AndroidEntryPoint
  21. Multi-module apps - Feature modules 3. Inject the dependency in

    the feature module ... override fun onCreate(savedInstanceState: Bundle?) { DaggerImageFeatureComponent.builder() .dependencies( EntryPointAccessors.fromApplication( applicationContext, ImageFeatureModule::class.java ) ) .build() .inject(this)
  22. Multi-module apps - Feature modules 3. Inject the dependency in

    the feature module ... override fun onCreate(savedInstanceState: Bundle?) { DaggerImageFeatureComponent.builder() .dependencies( EntryPointAccessors.fromApplication( applicationContext, ImageFeatureModule::class.java ) ) .build() .inject(this)
  23. Resources • Dependency injection with Hilt • Dagger Hilt •

    Using Hilt in your Android app Codelab • Migrating your Dagger app to Hilt Codelab • Scoping in Android and Hilt. Scoping an object A to another object B… | by Manuel Vivo | Android Developers • Hilt in multi-module apps • https://github.com/moyheen/HiltSampleApplication • Image by Gerd Altmann from Pixabay

More Decks by Moyinoluwa Adeyemi

Other Decks in Programming