Práctica de dagger - parte II

Inicialización de componente dagger

    private val mainComponent: MainComponent by lazy {
        initializeMainComponent()
    }

    private fun initializeMainComponent(): MainComponent {
        val component = (applicationContext as MainApp).appComponent
        return DaggerMainComponent.factory().create(component)
    }

Uso de dagger en otros módulos

Creación de interfaz para proveer dependencias

interface DogCollectionComponentProvider {
    fun provideDogCollectionComponent(): DogCollectionSubcomponent
}

Uso de interfaz en punto de entrada (actividad, fragmento, servicio, ...)

    val dogCollectionComponent =
        (fragmentActivity as DogCollectionComponentProvider).provideDogCollectionComponent()

(Opcional) Creación de clase para paso de dependencias externas desde módulo principal

data class DogCollectionDependencies(
    val isDebug: Boolean
)

Uso de clase con dependencias externas

    companion object {
        private const val BASE_URL = "https://dog.ceo/api/"
        private const val DEBUG_URL = "https://dog.ceo/api/"

        @Provides
        fun provideWebServiceRetrofit(dogCollectionDependencies: DogCollectionDependencies): DogCollectionWebService {
            return if (dogCollectionDependencies.isDebug) Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(DEBUG_URL)
                .build().create(DogCollectionWebService::class.java) else Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(BASE_URL)
                .build().create(DogCollectionWebService::class.java)
        }
    }

En módulo principal

Exponer subcomponente desde container de dependencias

    fun dogCollectionComponent(): DogCollectionSubcomponent.Factory

implementar interfaz para proveer componente, junto con dependencias externas

class MainActivity : AppCompatActivity(), DogCollectionComponentProvider {
    ...
    override fun provideDogCollectionComponent(): DogCollectionSubcomponent = mainComponent
        .dogCollectionComponent()
        .create(
            dogCollectionDependencies = DogCollectionDependencies(
                isDebug = BuildConfig.DEBUG
            )
        )
    ...
}

Otro ejemplo

Proveer componente con dependencias con alcance global

En otros módulos

class ExampleFirebaseMessagingService : FirebaseMessagingService() {
    @Inject
    lateinit var property: PropertyClass
    ...
    override fun onCreate() {
        (applicationContext as ExampleComponentProvider)
            .provideExampleComponent()
            .inject(this)
        super.onCreate()
    }
}

En módulo principal

class MyApplication: Application(), ExampleComponentProvider {
  val appComponent = DaggerApplicationComponent.create()

  override fun provideExampleComponent(): ExampleComponent {
    return appComponent.exampleComponent().create()
  }
}
@Singleton
@Component()
interface ApplicationComponent {
    ...
    fun exampleComponent(): ExampleComponent.Factory
}