Dagger注射器不适用于Kotlin中的"物体"

Nih*_*nth 17 singleton android kotlin dagger

花了很多时间试图弄清楚为什么我的匕首注射不起作用; 我意识到Kotlin中的"对象"类型是问题所在.

以下不起作用,注入的"属性"为空.

object SomeSingleton {

    @Inject
    lateinit var property: Property

    init {
        DaggerGraphController.inject(this)
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,以下DID工作正常:

class NotSingleton {

    @Inject
    lateinit var property: Property

    init {
        DaggerGraphController.inject(this)
    }
}
Run Code Online (Sandbox Code Playgroud)

我试过谷歌,我尝试了文档,但我无法指出这背后的原因.另请注意,我没有尝试使用JAVA,JAVA并没有内置单例的概念.

为什么会这样?为什么kotlin singleton无法注入成员但是常规非单身人士类可以?

Sim*_*mY4 13

如果您查看kotlin字节码,您会发现您编写的代码已翻译成以下内容:

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

    public final getProperty()LProperty
    ...

    public final setProperty(LProperty)V
    ...
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,实际字段是静态的,这使得它无法用于实例注入.您可以尝试@Inject通过这样做将注释移动到setter方法:

object SomeSingleton {
    @set:Inject
    lateinit var property: Property
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这仍然不起作用,我第一次遇到未初始化的字段错误......在那之后,我什至用@field:Inject 尝试过 NoClassDefFoundError,不幸的是同样的负面结果 (2认同)
  • 不适合我。编译期间出现异常`由以下原因引起:com.google.common.base.Preconditions.checkArgument(Preconditions.java:128) 处的 java.lang.IllegalArgumentException dagger.internal.codegen.writing.InjectionMethod.invoke(InjectionMethod.java:112)在 dagger.internal.codegen.writing.InjectionMethods$InjectionSiteMethod.invoke(InjectionMethods.java:358)` (2认同)

Vis*_*bre 12

解决此问题的方法是扩展包含要注入的字段的 BaseClass。

object SomeSingleton : BaseClass {
    ...
    ...
}

open class BaseClass{
    @Inject
    lateinit var property: Property

    init{
        YourDaggerComponent.inject(this)
    }

}
Run Code Online (Sandbox Code Playgroud)

这确实有效,尽管这会泄漏this,这是一个 android studio 警告,要摆脱它,使基类抽象,而是将字段注入到原始对象类中

object SomeSingleton : BaseClass {
    ...
    ... 
 // Add the init block here instead of the base class
 init{
        YourDaggerComponent.inject(this)
    }
}

abstract class BaseClass{
    @Inject
    lateinit var property: Property
    
   //Remove the init block from here

}
Run Code Online (Sandbox Code Playgroud)

你的 Dagger AppComponent 接口可以像这样,任何一个函数 def 都应该可以工作

interface Component{
    fun inject(someSingleton : SomeSingleton)
    //OR
    fun inject(baseClass: BaseClass)
}
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助....


Den*_*ski 6

我尝试使用dagger.Lazy<YourClass>并且有效

 @set:Inject
lateinit var authClient: dagger.Lazy<PlatformAuthClient>
Run Code Online (Sandbox Code Playgroud)

  • 我在尝试注入 kotlin 对象时遇到此错误:“Dagger 不支持注入 Kotlin 对象”。这是 Dagger 2.27 上的。 (7认同)