android – Dagger injection not working for "object" in Kotlin-ThrowExceptions

Exception or error:

After spending a ludicrous amount of time trying to figure out why my dagger injections weren’t working; I realised that the “object” type in Kotlin was the problem.

The following did not work, the injected “property” was null.

object SomeSingleton {

    @Inject
    lateinit var property: Property

    init {
        DaggerGraphController.inject(this)
    }
}

However, the following DID work just fine:

class NotSingleton {

    @Inject
    lateinit var property: Property

    init {
        DaggerGraphController.inject(this)
    }
}

I tried google, I tried the documentation but I could not pin point the reason behind this. Also note that I havent tried this with JAVA, JAVA doesnt have the concept of singletons built in anyway.

Why is this the case? Why is a kotlin singleton unable to inject members but a regular non-singleton class can?

How to solve:

If you look into kotlin bytecode you’ll find that the code you’ve written is translated into following:

public final class SomeSingleton {
    public static LProperty; property // <- Notice static field here

    public final getProperty()LProperty
    ...

    public final setProperty(LProperty)V
    ...
}

As you can see the actual field is static which makes it uneligible for instance injection. You may try to move @Inject annotation onto setter method by doing so:

object SomeSingleton {
    @set:Inject
    lateinit var property: Property
    ...
}

###

I tried to use dagger.Lazy<YourClass> and it works

 @set:Inject
lateinit var authClient: dagger.Lazy<PlatformAuthClient>

###

You may still need the @Singleton decorator on top of your object definition. That decorator doesn’t make your class ‘singleton’, it’s just used by Dagger to get all the dependencies in the same spot.

Leave a Reply

Your email address will not be published. Required fields are marked *