I've two modules :app
and :settings
. Here are my dagger configuration.
My component:
@ApplicationScope
@Component(
modules = [
AndroidInjectionModule::class,
AndroidSupportInjectionModule::class,
RoutingModule::class,
SettingsModule::class
]
)
interface ELanguageComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ELanguageComponent
}
fun inject(application: BaseELanguageApplication)
}
The RoutingModule
:
@Module
class RoutingModule {
@Provides
fun ProvidesettingsFragmentRouter(router: SettingsRouter): SettingsFragment.Router = router
}
The SettingsRouter
:
class SettingsRouter @Inject constructor(
private val applicationStateManager: ApplicationStateManager
) : SettingsFragment.Router
The SettingsModule
:
@Module
abstract class SettingsModule {
@ActivityScope
@ContributesAndroidInjector(modules = [SettingsFragmentModule::class, ApplicationStateManagerModule::class])
abstract fun settingsActivity(): SettingsActivity
}
@Module
abstract class ApplicationStateManagerModule {
@Module
companion object {
@JvmStatic
@Provides
fun bindApplicationStateManager(settingsActivity: SettingsActivity): ApplicationStateManager = settingsActivity
}
}
My SettingsFragmentModule
:
@Module
abstract class SettingsFragmentModule {
@FragmentScope
@ContributesAndroidInjector
abstract fun settingsFragment(): SettingsFragment
}
And the SettingsFragment.Router
is injected inside my SettingsFragment
:
class SettingsFragment : DaggerFragment() {
@Inject
lateinit var router: Router
...
}
I've already found and read this article but it does not help much since the error is not that explanatory:
[Dagger/MissingBinding] com.altissia.common.authentication.ApplicationStateManager cannot be provided without an @Provides-annotated method. public abstract interface ELanguageComponent { ^ com.altissia.common.authentication.ApplicationStateManager is injected at com.altissia.router.SettingsRouter(applicationStateManager, …) com.altissia.router.SettingsRouter is injected at com.altissia.injection.module.RoutingModule.ProvidesettingsFragmentRouter(router) com.altissia.settings.fragment.SettingsFragment.Router is injected at com.altissia.settings.fragment.SettingsFragment.router com.altissia.settings.fragment.SettingsFragment is injected at dagger.android.AndroidInjector.inject(T) [com.altissia.injection.component.ELanguageComponent → com.altissia.settings.injection.module.SettingsModule_SettingsActivity.SettingsActivitySubcomponent → com.altissia.settings.injection.module.SettingsFragmentModule_SettingsFragment.SettingsFragmentSubcomponent]
What am I missing here? ApplicationStateManager
is provided through the ApplicationStateManagerModule
which is installed inside SettingsModule
.
The situation in the linked article applies here.
SettingsFragment
requests a SettingsFragment.Router
.SettingsFragment.Router
depends on SettingsRouter
, and this binding is in the application component.SettingsRouter
depends on ApplicationStateManager
via an @Inject
constructor.ApplicationStateManager
binding is in your (generated) activity subcomponent.Thus, you have a binding in the parent component which requires a binding in a subcomponent. As described in the article, the easiest way to fix this is to move RoutingModule
into your activity (or fragment) subcomponent.