I'm learning dagger2 with a module architecture. And I think, something is not clear to me, for example
in module utilites
i have di
package
class UtilsComponent
@Component(modules = [UtilsModule::class])
interface UtilsComponent {
fun getResourceProvider() : IResourceProvider
fun getNetworkProvider(): INetworkProvider
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): UtilsComponent.Builder
fun build(): UtilsComponent
}
}
@Module
abstract class UtilsModule {
@Binds
abstract fun bindContext(application: Application): Context
@Module
companion object {
@Provides
@JvmStatic
fun bindResourceProvider(context: Context): IResourceProvider {
return ResourceProvider(context = context)
}
@Provides
@JvmStatic
fun bindNetworkProvider(context: Context): INetworkProvider {
return NetworkProvider(context = context)
}
}
}
then in app
package in AppComponent
i included all modules
@Component(
dependencies = [UtilsComponent::class],
modules = [
AndroidInjectionModule::class,
ActivityBindingModule::class,
MainModule::class // test module
]
)
@AppScope
interface AppComponent: AndroidInjector<App> {
// inject to ...
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): AppComponent.Builder
fun utilsComponent(utilsComponent: UtilsComponent): AppComponent.Builder
fun build(): AppComponent
}
}
In the app component, I have MainModule
- this is my test module, so this module looks like this
@Module
class MainModule {
@Provides
fun getMainPresenter(networkProvider: NetworkProvider): MainPresenter {
return MainPresenter(networkProvider)
}
}
when I run the app, I have an error
[Dagger/MissingBinding] com.example.utilities.di.UtilsModule cannot be
provided without an @Provides-annotated method. public abstract
interface AppComponent extends
dagger.android.AndroidInjector<com.example.testmoduleapp.App> {
^
com.example.utilities.di.UtilsModule is injected at
com.example.testmoduleapp.di.modules.MainModule.getMainPresenter(utilsModule)
com.example.testmoduleapp.ui.activities.main.MainPresenter is injected at
com.example.testmoduleapp.ui.activities.main.MainActivity.mainPresenter
com.example.testmoduleapp.ui.activities.main.MainActivity is injected at
dagger.android.AndroidInjector.inject(T) [com.example.testmoduleapp.di.AppComponent →
com.example.testmoduleapp.di.modules.ActivityBindingModule_MainActivity.MainActivitySubcomponent]
I understand that the error is because I have not a module witch return NetworkProvider
object, but I can't understand how I can get this object from UtilsModule
also in App
@Inject
lateinit var androidInjector : DispatchingAndroidInjector<Any>
override fun androidInjector(): AndroidInjector<Any> = androidInjector
companion object{
lateinit var appComponent: AppComponent
}
override fun onCreate() {
super.onCreate()
initializeDagger()
}
private fun initializeDagger() {
appComponent = DaggerAppComponent
.builder()
.application(this)
.utilsComponent(provideUtilsComponent())
.build()
}
private fun provideUtilsComponent(): UtilsComponent {
return DaggerUtilsComponent
.builder()
.application(this)
.build()
}
In Dependencies Graph
You already provide INetworkProvider
so when you need NetworkProvider
it means Dagger
can not be resolved. Change to this, don't forget to change constructor MainPresenter
to INetworkProvider
@Provides
fun getMainPresenter(networkProvider: INetworkProvider): MainPresenter {
return MainPresenter(networkProvider)
}
but i cant understand how i can get this object from UtilsModule
For your question, in UtilComponent
you already exposed getNetworkProvider()
it means any Componenent
dependencies to UtilsComponent
can be get it.