Reputation: 1609
I am using Dagger2
and I want to know if it is possible to use the new Android Injector
for dependent components? I have seen a few tutorials that use subcomponents and the base App component will just inject everything.
AppComponent
@Singleton
@Component(modules = [AndroidSupportInjectionModule::class])
interface ApplicationComponent {
fun inject(app: App)
@Component.Builder
interface Builder {
fun build(): ApplicationComponent
@BindsInstance
fun app(app: Context): Builder
}
}
QueueComponent
@QueueScope
@Component(dependencies = arrayOf(ApplicationComponent::class), modules = [ScreenBindingModule::class])
interface QueueComponent {
}
ScreenBindingModule
@Module
abstract class ScreenBindingModule {
@ContributesAndroidInjector()
abstract fun queueActivity(): QueueActivity
}
In the onCreate
I have added AndroidInjection.inject(this)
but the problem is that the app crashes with the exception:
Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class....
Upvotes: 0
Views: 326
Reputation: 95654
No, this will not work without more configuration. As in AndroidInjection.inject
:
Application application = activity.getApplication();
if (!(application instanceof HasActivityInjector)) { /* ... */ }
Given an Activity there's no easy way to determine which wider-than-Activity-scoped object should be used to create the Activity's subcomponent, so dagger.android tries to cast the Application to the type HasActivityInjector. Your Application evidently exposes HasActivityInjector to get that error message—likely by marking DaggerApplication or your custom subclass of DaggerApplication in your manifest—but that implementation just returns the DispatchingAndroidInjector<Activity>
that searches a multibindings map.
Though @ContributesAndroidInjector
automatically installs into that map, each of your Components (ApplicationComponent and QueueComponent) contains a different map, and your DaggerApplication only consults the one in ApplicationComponent.
In order to make this work with component dependencies, you would need to have your Application subclass's activityInjector
method return a different AndroidInjector implementation, which creates/fetches a QueueComponent instance and reads the multibound Maps (which would necessarily be exposed on QueueComponent). Unfortunately, there isn't really a way to bind multiple elements into your ApplicationComponent's existing multibound map, as tracked in https://github.com/google/dagger/issues/687, so making this work would involve a custom AndroidInjector implementation at least.
Upvotes: 1
Reputation: 311
@ContributesAndroidInjector()
abstract fun queueActivity(): QueueActivity
Which module contains this part of code? In QueueComponent You are added ScreenBindingModule::class, but define injector factory in another class - QueeScrennBindingModule::classs.
It's just a typo or it's really two different classes?
Upvotes: 0