I decided to learn dagger
dependency injection framework. After some tutorials I try to implement dagger into my project. However I got this error
com\assigment\di\component\AppComponent.java:11: error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends android.app.Activity>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.app.Activity>>> cannot be provided without an @Provides-annotated method.
public abstract void inject(@org.jetbrains.annotations.NotNull()
^
java.util.Map<java.lang.Class<? extends android.app.Activity>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.app.Activity>>> is injected at
dagger.android.DispatchingAndroidInjector.<init>(injectorFactories)
dagger.android.DispatchingAndroidInjector<android.app.Activity> is injected at
assigment.com.assigment.App.activityInjector
assigment.com.assigment.App is injected at
assigment.com.assigment.di.component.AppComponent.inject(assigment.com.assigment.App)
I try to solve this for 2 days but with no luck. So here's how I set up my project
class App : Application(), HasActivityInjector {
@Inject
lateinit var activityInjector: DispatchingAndroidInjector<Activity>
lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent
.builder()
.appModule(AppModule())
.build()
}
override fun activityInjector(): AndroidInjector<Activity> {
return activityInjector
}
}
Here's my app component
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent : AndroidInjector<App> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
override fun inject(app: App)
}
and here's my appModule class
AppModule
@Module
class AppModule {
private val url = "http://test.lt/v1/"
@Provides
@Singleton
fun provideApplication(app: Application): Context = app
}
So what I'm missing with this implementation?
Add AndroidInjectionModule.class and ActivityBuilder.class to your AppComponent
@Singleton
@Component(modules = [AndroidInjectionModule::class, AppModule::class, ActivityBuilder::class ])
interface AppComponent : AndroidInjector<App> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
override fun inject(app: App)
}
You have two problems.
To get rid of the compiler error add AndroidInjectionModule::class
to Component modules:
@Singleton
@Component(modules = [AndroidInjectionModule::class, AppModule::class])
interface AppComponent : AndroidInjector<App> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
override fun inject(app: App)
}
With @Component.Builder
annotated interface you define the builder interface with an annotated @BindsInstance
method application()
(note that there is not an appModule
method declared in the Builder).
With such declaration you can build your component using application(this)
:
appComponent = DaggerAppComponent
.builder()
.application(this)
.build()
In this way this
application instance is bound inside the component.
Just as a side note: Binding Instances are documented here, but personally I found the explanation quite hard to grasp for someone learning dagger, like me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With