My app has a library (Core Library) we maintain as a module in the project and we include as a gradle dependency like this:
build.gradle
dependencies {
api project(':core')
}
I'm trying to integrate this Core Library as a Dagger subcomponent the way it's shown on this RW tutorial.
The problem I'm facing is that all of the @Provides annotated methods inside CoreModule can't be found and when digging into the compiled DaggerAppComponent generated file, the corresponding providing methods are missing, even though they're supposed to be annotated correctly. Do you guys have an idea of I'm doing wrong?
This is the error message I get. CoreSettings is annotated as a @Provides method but still can't be found.
android/di/AppComponent.java:12: error: [Dagger/MissingBinding] com.core.util.CoreSettings cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface AppComponent {
^
com.core.util.CoreSettings is injected at com.base.BaseVideoPlayerActivity.coreSettings
com.base.BaseVideoPlayerActivity is injected at
com.di.AppComponent.inject(com.base.BaseVideoPlayerActivity)
It is also requested at:
com.base.BaseVideoPlayerActivity.coreSettings
The following other entry points also depend on it:
com.di.AppComponent.inject(com.ui.LiveVideoActivity)
DaggerAppComponent.java (Here the provider method for CoreSettings, declared in CoreModule, is missing)
private final class CoreComponentImpl implements CoreComponent {
private CoreComponentImpl() {
}
@Override
public void inject(FeedDownloadService arg0) {
}
}
I have tried many different things like including the CoreModule directly in the AppComponent which works wonderfully, but not when it's part of the subcomponent.
Here is the file breakdown:
AppComponent.kt
@ApplicationScope
@Component(modules = [UtilsModule::class, CoreLibraryModule::class])
interface AppComponent {
@Component.Factory
interface Factory {
fun create(modules: UtilsModule): AppComponent
}
fun coreComponentFactory(): CoreComponent.Factory
/**
* Classes that can be injected by this Component
*/
fun inject(app: AppApplication)
}
UtilsModule.kt
@Module
class UtilsModule(private val ctx: Context) {
@ApplicationScope
@Provides
fun provideApplicationContext(): Context = ctx
}
CoreLibraryModule.kt
/**
* Wrapper module for the CoreComponent to be included in the AppComponent
*/
@Module(subcomponents = [CoreComponent::class, SplashComponent::class])
object CoreLibraryModule
CoreComponentProvider.kt
/**
* Interface that provides a CoreComponent that Core Library classes can use for injection.
* This interface must be implemented by the Application subclass.
*/
interface CoreComponentProvider {
fun getCoreComponentFactory(): CoreComponent.Factory
}
CoreComponent.kt
/**
* Subcomponent that provides injection mechanism to Core Library classes
*/
@Subcomponent(modules = [CoreModule::class])
interface CoreComponent {
@Subcomponent.Factory
interface Factory {
fun create(module: CoreModule): CoreComponent
}
/**
* Classes that can be injected by this Component
*/
fun inject(app: FeedDownloadService)
}
CoreModule.kt
@Module
class CoreModule {
@ApplicationScope
@Provides
fun provideCoreSettings(): CoreSettings = CoreSettings.getInstance()
}
BaseVideoPlayerActivity.kt
class BaseVideoPlayerActivity: Activity {
@Inject
lateinit var coreSettings: CoreSettings
override fun onCreate(savedInstanceState: Bundle?) {
// Inject dependencies via Dagger here.
(application as AppApplication).appComponent.inject(this)
}
}