Implementing a simple Dagger2 sample
Solution 1:
AppModule.kt: Provide the application context. No need to write @singleton @provides for your Test* classes (will see why)
@Module
class AppModule {
@Provides
@Singleton
fun provideApplication(app: App): Context = app.applicationContext
}
AppComponent.kt: @Component.Builder
is deprecated IIRC. Use @Component.Factory
. And replace AndroidInjectionModule::class
with AndroidSupportInjectionModule::class
since we are using dagger-android-support
and android's *Compat*
stuff. Refer a new module here called ActivityModule::class
.
@Singleton
@Component(modules = [
ActivityModule::class
AndroidSupportInjectionModule::class,
AppModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Factory
abstract class Factory : AndroidInjector.Factory<App>
}
TestClass.kt & TestOperator.kt: Since you were providing singletons by writing @singleton and @provides method, I assume you want them to be singletons. Just annotate the class definition with @Singleton and dagger will take care of it. No need to write @Provides methods.
@Singleton
class TestClass @Inject constructor(private val testOperator: TestOperator) {
fun getRandomValueFromCTest(): Int = testOperator.generateRandomNumber()
}
@Singleton
class TestOperator @Inject constructor() {
fun generateRandomNumber(): Int = Random.nextInt()
}
App.kt: Using factory instead of builder since @Component.Builder
is deprecated.
class App : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.factory().create(this)
}
}
ActivityModule.kt: Provide a module to dagger to create your activities.
@Module
interface ActivityModule {
@ContributesAndroidInjector
fun provideMainActivity(): MainActivity
}
MainActivity.kt: Finally, extend from DaggerAppCompatActivity
.
class MainActivity : DaggerAppCompatActivity() {
@Inject
lateinit var testClass: TestClass
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onResume() {
super.onResume()
val x = testClass.getRandomValueFromCTest()
}
}
I believe this should run without issues. For more reference you could look into this sample and the new simpler docs at dagger.dev/android
Solution 2:
You are missing the actual injection call.
class MainActivity : AppCompatActivity() {
@Inject
lateinit var testClass: TestClass
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}