I am trying to do a field injection in a non Activity class, but I am always getting that the field has not been initialized/null. I have read Can I use Dagger 2's field injection in Kotlin?, also Dagger 2 on Android @Singleton annotated class not being injected, and still have the same problem. Here is how I have setted it up
This is the model class
class Greetings {
val sayHello: String = "Hello from Dagger 2"
}
This is the module class
@Module
class GreetingsModule {
@Provides
@Singleton
fun providesGreetings(): Greetings {
return Greetings()
}
}
This is the component
@Singleton
@Component(modules = arrayOf(GreetingsModule::class))
interface GreetingsComponent {
fun inject(mainActivity: MainActivity)
fun inject(testGreetings: TestGreetings)
}
And the class that extends from Application
class App: Application() {
private lateinit var greetingsComponent: GreetingsComponent
override fun onCreate() {
super.onCreate()
greetingsComponent = DaggerGreetingsComponent.builder().build()
}
fun getGreetings() = greetingsComponent
}
And this is how I am injecting it into another class and where is null/not initialized
class TestGreetings {
@Inject
lateinit var greetings: Greetings
fun checkIfNull() {
if (greetings != null) {
Log.d("INFO", "${ greetings.sayHello}")
} else {
Log.d("INFO", "null !!!!!!")
}
}
}
What exactly I am doing wrong??
ok, I'll try to answer
You can't use Field Injection which is Greetings
in TestGreetings
class because Dagger doesn't know how to inject it.
Field Injection is usually used, for components that is related to Android Framework, so in your case is MainActivity
TestGreetings
class is not Android Framework class, so it is better to use Constructor Injection, like this
class TestGreetings(private val greetings: Greetings) {
fun checkIfNull() {
if (greetings != null) {
Log.d("INFO", "${ greetings.sayHello}")
} else {
Log.d("INFO", "null !!!!!!")
}
}
}
In order for Dagger to know how to initialize TestGreetings
class, you need to define it in GreetingsModule
class
@Module
class GreetingsModule {
...
@Provides
@Singleton
fun providesTestGreetings(greetings: Greetings): TestGreetings {
return TestGreetings(greetings)
}
}
Now you can use TestGreetings
class in MainActivity
class MainActivity: AppCompatActivity() {
@Inject
lateinit var testGreetings: TestGreetings
override fun onCreate(savedInstanceState: Bundle?) {
...
testGreetings.checkIfNull()
}
}
Lastly, you can remove fun inject(testGreetings: TestGreetings)
in GreetingsComponent
P.s. Make sure your Dagger setup in MainActivity
is correct
Hopefully this clear the things out :)