1

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??

Tony
  • 159
  • 1
  • 11
  • how you inject it in activity? – IR42 Jul 13 '20 at 09:25
  • how do you inject `TestGreetings`? can you show the code for that part? – Franz Andel Jul 13 '20 at 09:35
  • I thought that by adding the inject methond on the component was enough, check the GreetingsComponent interface, do I need something else? – Tony Jul 13 '20 at 09:48
  • I mean the usage of `fun inject(testGreetings: TestGreetings)`. Can you show where do you use this? – Franz Andel Jul 13 '20 at 09:58
  • @FranzAndel thxs a lot for your time, I really appreciate this. Currently I am not using this method, can you please tell me please how and where should I call it? I am trying to learn dagger, but apparently is harder than I thought. I cant call it like I did on the MainActivity, which I did like this (application as App).getGreetings().inject(this) – Tony Jul 13 '20 at 10:14

1 Answers1

0

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 :)

Franz Andel
  • 1,326
  • 12
  • 20