1

Basically, I wanted to test if TheCoffee was automatically "injected". But I could not find DaggerMyComponent. I think I must have done something wrong, but what?

Under the MainActivity,

@Component(modules=arrayOf(MyModule::class))
@Singleton
interface MyComponent
{
    fun inject(coffee: CoffeeShop)
}

@Module
class MyModule
{
    @Provides
    @Singleton
    @ForApplication
    fun provideCoffee():Coffee
    {
        return Coffee("Bad coffee");
    }
}

data class Coffee(var Name:String)

class CoffeeShop
{
    @Inject
    var TheCoffee:Coffee? = null;
}

@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class ForApplication

build.gradle

apply plugin: 'kotlin-kapt'
...
kapt {
    generateStubs = true
}
....
dependencies {
    compile 'com.google.dagger:dagger-android:2.13'
    kapt 'com.google.dagger:dagger-android-processor:2.13'
    compileOnly 'com.google.dagger:dagger:2.13'
    kapt 'com.google.dagger:dagger-compiler:2.13'
Damn Vegetables
  • 11,484
  • 13
  • 80
  • 135
  • Does it compile / build? – David Medenjak Nov 12 '17 at 10:26
  • Yes. But after the build succeeded, when I type `DaggerMyComponent`, it fails to find that class. – Damn Vegetables Nov 12 '17 at 10:26
  • I doubt that it can build, because `Coffee` can't be provided to `CoffeeShop`, since you're not using constructor injection or providing it from a component. Also you should be using constructor injection instead of field injection with `CoffeeShop` since you can create it yourself. You should look for the errors, or verify that Dagger runs, but your gradle part looks good AFAICT – David Medenjak Nov 12 '17 at 10:31
  • Yesterday someone asked a similar question where they also (mis)used field injection, see [here](https://stackoverflow.com/q/47242150/1837367) – David Medenjak Nov 12 '17 at 10:34
  • `TheCoffee` can be `null` so I think the class can be compiled without Dagger. The build succeeds and I can run the app. But I am not sure whether Dagger ran or not. Other than adding those in build.gradle, do I need to do something else? How to check if Dargger has run? – Damn Vegetables Nov 12 '17 at 10:42
  • I did something to the build.gradle and now build fails. The message was, `error: Dagger does not support injection into private fields. private Coffee TheCoffee;`. Kotlin properties are 'public' by default, and explicitly adding 'public' before `TheCoffee` made no difference. I guess even though I wrote `TheCoffee` as `public`, Kotlin hides it and creates a getter/a setter. So, in Kotlin, I cannot use field injection? – Damn Vegetables Nov 12 '17 at 11:28
  • Kotlin does support field injection. Please read the error carefully, read the full name of the class, and check there. Often you forget about some test or class in another package – David Medenjak Nov 12 '17 at 12:08
  • Thank you. I changed `TheCoffee` to a constructor injection and it now generated the component. – Damn Vegetables Nov 12 '17 at 12:38
  • Small note about field injection: you *can* inject into fields if you annotate them with the `@JvmField` annotation. It makes the field non-private so there should not be any problems with Dagger. Please also be sure the `@Inject` annotation you put on property is actually being put its backing field (you can write `@field:Inject` to specify the annotation target explicitly). – yanex Nov 13 '17 at 03:36

0 Answers0