I am modularizing one of my Android App. In which I am using Dagger for Dependency Injection. It was working fine with one module.
But since I created 3 modules now I am facing many issues mainly because of Dagger. Modules inr app are app, core, feature. I am trying to keep all shared code in the base module. So I have integrated Dagger in my core module using article. When I trying to use custom Scope (ie AppScope) for my AppComponent in order to connect it with the core module. I am getting below error. However Singleton is working.
E:\shahbaz\ultimate-downloader\app\build\tmp\kapt3\stubs\debug\matrixsystems\ultimatedownloader\di\components\AppComponent.java:12: error: [Dagger/IncompatiblyScopedBindings] matrixsystems.ultimatedownloader.di.components.AppComponent scoped with @matrixsystems.ultimatedownloader.di.AppScope may not reference bindings with different scopes:
public abstract interface AppComponent {
Code I am using :
AppComponent.kt
@AppScope // Singleton is working
@Component(modules = [AndroidInjectionModule::class, AppModule::class])
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(app: AppController): Builder
fun build(): AppComponent
}
fun inject(app: AppController)
}
AppModule.kt
@Module(includes = [ActivityModule::class, ViewModelModule::class])
class AppModule {
/**
* Application application level context.
*/
@Singleton
@Provides
fun provideContext(application: AppController): Context {
return application.applicationContext
}
/**
* Application resource provider, so that we can get the Drawable, Color, String etc at runtime
*/
@Provides
@Singleton
fun providesResources(application: AppController): Resources = application.resources
}
ActivityModule.kt
@Module(includes = [FragmentModule::class]) // Including Fragment Module Available For Activities
internal abstract class ActivityModule {
/**
* Marking Activities to be available to contributes for Android Injector
*/
@ContributesAndroidInjector
abstract fun contributeMainActivity(): MainActivity
}
FragmentModule.kt
@Module
internal abstract class FragmentModule {
@ContributesAndroidInjector
internal abstract fun contributeDownloadsFragment(): DownloadsFragment
}
ViewModelModule.kt
@Module
internal abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
abstract fun bindMainViewModel(mainViewModel: MainViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(DownloadsViewModel::class)
abstract fun bindDownloadsViewModel(downloadsViewModel: DownloadsViewModel): ViewModel
/**
* Binds ViewModels factory to provide ViewModels.
*/
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
AppController.kt
class AppController : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
override fun onCreate() {
super.onCreate()
AppInjector.initApp(this)
}
override fun activityInjector(): AndroidInjector<Activity> {
return dispatchingAndroidInjector
}
}
AppInjector.kt
object AppInjector {
fun initApp(app: AppController) {
DaggerAppComponent.builder().application(app).build().inject(app)
app.registerActivityLifecycleCallbacks(object :
Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
handleActivity(activity)
}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
})
}
private fun handleActivity(activity: Activity) {
if (activity is HasSupportFragmentInjector) {
AndroidInjection.inject(activity)
}
(activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(
object : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentCreated(
fm: FragmentManager,
f: Fragment,
savedInstanceState: Bundle?
) {
if (f is Injectable) {
AndroidSupportInjection.inject(f)
}
}
}, true
)
}
}
I have spent 2 days but still no luck. I just want to add functional core module with Dagger. Any working article or sample code which I can use without making much changes in my existing app module is highly appreciated.