I am using Dagger 2.14.1 in my Android application and migrated recently from 2.10. The new version makes it much easier to inject Activities and Fragments, but I can't find a way to inject a custom class where I cannot change the constructor as well. With 2.10 I could write custom inject functions and then use them to simply inject any class:
Simplified Dagger 2.10 Injection with Kotlin:
@Singleton
@Component(dependencies = [], modules = [ApplicationModule::class, ...])
interface ApplicationComponent {
fun application(): App
fun inject(authenticationActivity: AuthenticationActivity)
fun inject(converters: Converters)
// ...
}
class App : Application() {
companion object {
@JvmStatic
lateinit var component: ApplicationComponent
}
override fun onCreate() {
super.onCreate()
component = DaggerApplicationComponent.builder()
.applicationModule(ApplicationModule(this))
.build()
}
}
// This class is used by the Room database framwork and I cannot change the constructor and do class Converters @Inject constructor(private val gson: Gson) {
class Converters {
@Inject
protected lateinit var gson: Gson
init {
App.component.inject(this)
}
// ...
}
Simplified Dagger 2.14.1 Injection with Kotlin doesn't provide me with a ApplicationComponent Object to inject my custom classess:
@Singleton
@Component(modules = [ApplicationModule::class, ...])
interface ApplicationComponent : AndroidInjector<App> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>()
fun inject(converters: Converters) // doesn't work!
}
class App : Application(), HasActivityInjector {
@Inject
lateinit var activityInjector: DispatchingAndroidInjector<Activity>
override fun onCreate() {
super.onCreate()
// From where do I get my component to call .inject() from another class?
DaggerApplicationComponent.builder().create(this).inject(this)
}
override fun activityInjector(): AndroidInjector<Activity> = activityInjector
}
In short: the DaggerApplicationComponent.builder().create(this)
returns an AndroidInjector<App!>
Object. This Object only has one .inject()
functions which only accepts my App
Class. So I cannot inject anything else.
Of course there is a lot missing, but I wanted to only post the relevant code. My Dagger 2.14.1 implementation works and all my dependencies in Activities, Fragments and View Models get injected.
I am quite new to Dagger and the more I use it the more I love it, but I couldn't figure out on how to inject custom classes where I cannot change the constructor. Thanks for you help!
Try this:
class App : Application(), HasActivityInjector {
@Inject
lateinit var activityInjector: DispatchingAndroidInjector<Activity>
companion object {
@JvmStatic
lateinit var instance: App
}
@Inject
lateinit var component: ApplicationComponent
override fun onCreate() {
super.onCreate()
instance = this
DaggerApplicationComponent.builder().create(this).inject(this)
}
override fun activityInjector(): AndroidInjector<Activity> = activityInjector
}
Then
object Injector {
@JvmStatic fun get(): ApplicationComponent = App.instance.component
}
Now you can do
class Converters {
@Inject
protected lateinit var gson: Gson
init {
Injector.get().inject(this)
}