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结构
Dagger2 + Kotlin:lateinit 属性尚未初始化