我想使用Dagger 2提供一个函数作为依赖项:

@Module
class DatabaseModule {

    @Provides
    @Singleton
    fun provideDatabase(application: Application, betaFilter: (BetaFilterable) -> Boolean): Database {
        return Database(application, BuildConfig.VERSION_CODE, betaFilter)
    }

    @Provides
    @Suppress("ConstantConditionIf")
    fun provideBetaFiler(): (BetaFilterable) -> Boolean {
        return if (BuildConfig.FLAVOR_audience == "regular") {
            { it.betaOnly.not() }
        } else {
            { true }
        }
    }

}

不幸的是,它似乎不起作用:

[dagger.android.AndroidInjector.inject(T)] kotlin.jvm.functions.Function1<? 
super com.app.data.BetaFilterable,java.lang.Boolean> 
cannot be provided without an @Provides-annotated method.

What am I missing here?

推荐答案

Yes, this can be done in Kotlin.

You need to add @JvmSuppressWildcards at the injection site to ensure the signature matches. (source)

为了验证这一点,我写了以下内容:

import dagger.Component
import dagger.Module
import dagger.Provides
import javax.inject.Singleton

class G constructor(val function: Function1<Int, Boolean>)

@Singleton
@Module
class ModuleB {
    @Provides
    fun intToBoolean(): (Int) -> Boolean {
        return { it == 2 }
    }
    @JvmSuppressWildcards
    @Provides fun g(intToBoolean: (Int) -> Boolean): G {
        return G(intToBoolean)
    }
}

@Singleton
@Component(modules = [ModuleB::class])
interface ComponentB {
    fun g(): G
}

val componentB = DaggerComponentB.create()
val g = componentB.g()
println(g.function(2)) // true
println(g.function(3)) // false

Background: Examining @Kiskae's response, it seems the problem is that a parameter of function type in Kotlin becomes contravariant on its own parameter types when the code is converted to Java bytecode. If this doesn't make sense to you, don't worry. It's not necessary to understand it to use the technique I show above.

Kotlin相关问答推荐

如何在Docker中使用Selenium和chromedriver?

为何Kotlin标准库中的AND和OR函数不能像&&和||一样进行短路运算?

为什么在jacksonObjectMapper上将DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES设置为false无效?

如何在 Kotlin 中为类方法调用传递变量

Kotlin:我可以将函数分配给 main 的伴随对象中的变量吗?

Kotlin 协程按顺序执行,但仅在生产机器上执行

如何在 Kotlin 中不受约束?

使用 Compose for Desktop Bundle 文件

有没有办法在spring webflux和spring data react中实现分页

Kotlin Compose,在行中对齐元素

runInTransaction 块内的挂起方法

使用 clear() 删除 EncryptedSharedPreferences 不起作用

Mockito 的 argThat 在 Kotlin 中返回 null

kotlin RecyclerView分页

如何根据ArrayList的对象属性值从中获取最小/最大值?

WebFlux 功能:如何检测空 Flux 并返回 404?

Kotlin flatMap - map

kotlin中密封类和密封接口的区别是什么

Kotlin 的数据类 == C# 的 struct ?

Android Jetpack Compose - 图像无法zoom 到框的宽度和高度