Kotlin + Dagger2:不能在没有 @Inject 构造函数或 @Provides- 或 @Produces-annotated 方法的情况下提供

Posted

技术标签:

【中文标题】Kotlin + Dagger2:不能在没有 @Inject 构造函数或 @Provides- 或 @Produces-annotated 方法的情况下提供【英文标题】:Kotlin + Dagger2: cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method 【发布时间】:2018-06-14 16:37:47 【问题描述】:

我收到以下错误:

错误:(8, 1) 错误:如果没有 @Inject 构造函数或 @Provides- 或 @Produces-annotated 方法,则无法提供 java.lang.String。

我一直在尝试制作一个提供两个合格字符串的模块。这是匕首的简化设置。

@Singleton
@Component(modules = [GreetingsModule::class])
interface AppComponent 
    fun inject(activity: MainActivity)


@Qualifier annotation class Spanish
@Qualifier annotation class French
@Qualifier annotation class English

@Module
@Singleton
class GreetingsModule 

    @Provides
    @Spanish
    fun providesHola(): String = "Hola mundo! - From Dagger"

    @Provides
    @English
    fun providesHello(): String = "Hello world! - From Dagger"


注入是在 MainActivity 中完成的:

class MainActivity : AppCompatActivity() 

    @Inject @Spanish
    lateinit var holaMundoText: String

    @Inject @English
    lateinit var helloWorldText: String


我也尝试直接在组件中声明 getter,但失败并出现同样的错误。将模块方法声明为静态时也是如此。

正如应该的那样,代码只使用一个@Provide 就可以正常工作,然后将字符串注入到两个字段中。我认为问题出在限定符上。

非常感谢任何帮助。


使用:

android Studio 3.0.1 Kotlin 1.2.10 匕首 2.14.1

【问题讨论】:

您的GreetingsModule 中有@Provides @French 注释方法吗? 哎呀,我从模块中删除了那个,但把它留在了活动中。我更新了帖子。谢谢 @crgarridos 您是否尝试仅使用问题中的代码进行编译?只是为了确保问题不在您的其余代码中。 @LordRaydenMK 是的,我只尝试使用此代码,最初它使用 DaggerAndroid 类。我删除了所有内容并手动离开。我已经花了超过 2 年的时间试图让它发挥作用。 @Onik 该模块不依赖任何东西,反正我试过了,得到了相同的 u.u 【参考方案1】:

使用 JSR-330 + Kotlin(Dagger2 是一个实现)在限定和命名注入方面存在一些问题。通过最近查看 Github 上 Dagger2 项目的积压工作,我知道 Google 团队希望在即将发布的版本中提供更主动的帮助/更有用的错误消息(无时间表)。

您缺少的是链接文档中所述的@field:<Qualifier> annotation use-type targets。所以试试吧;

@Inject @field:Spanish lateinit var holaMundoText: String

【讨论】:

它就像一个亮点,你是一个救星。感谢您的解释+文档 我花了一个小时试图找出问题所在,这个解决方案救了我,谢谢! 所以这是为了使用限定符,使用命名注释呢?编辑:显然你可以使用这样的东西 @field:Named("aaa") 更简洁的变体:\@field:[Inject Spanish] 而不是 \@Inject @field:Spanish【参考方案2】:

我认为问题出在 Kotlin 编译器中,它不知道放置此类注释(参数、设置器、字段等)的位置。为了避免丑陋的@field:Spanish(西班牙语注释类被标记为限定符注释),我找到了另一个解决方案:只需使用带有适当参数的目标注释标记西班牙语注释,参见示例:

@Qualifier
@Target(FUNCTION, CONSTRUCTOR, FIELD, VALUE_PARAMETER, PROPERTY_SETTER)
annotation class Spanish

那么你可以使用:

@Inject @Spanish
lateinit var holaMundoText: String

【讨论】:

以上是关于Kotlin + Dagger2:不能在没有 @Inject 构造函数或 @Provides- 或 @Produces-annotated 方法的情况下提供的主要内容,如果未能解决你的问题,请参考以下文章

kotlin + Dagger2 :没有@Provides-annotated 方法就无法提供

没有Dagger2的Android Kotlin MVVM结构

kotlin 缺少提供程序的 Dagger 2 错误

Dagger2 + Kotlin:lateinit 属性尚未初始化

Dagger2 Qualifier 不适用于 Kotlin?

dagger2 和 kotlin 的 Android 单元测试问题