我想使用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.
我在这里想念什么?
答案 0 :(得分:4)
是的,这可以在Kotlin中完成。
您需要在注射位置添加@JvmSuppressWildcards以确保 签名匹配。 (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
答案 1 :(得分:3)
它不起作用,因为为了允许调用具有超类型的函数代替lambda(可以使用(Any) -> Boolean
和(BetaFilterable) -> Boolean
),因为函数将参数作为参数生成字节码以允许这个。
以下代码:
object Thing
fun provide(): (Thing) -> Boolean {
TODO()
}
fun requires(func: (Thing) -> Boolean) {
TODO()
}
产生以下签名:
签名
()Lkotlin/jvm/functions/Function1<LThing;Ljava/lang/Boolean;>
;声明:
kotlin.jvm.functions.Function1<Thing, java.lang.Boolean> provide()
签名
(Lkotlin/jvm/functions/Function1<-LThing;Ljava/lang/Boolean;>;)V
声明:
void requires(kotlin.jvm.functions.Function1<? super Thing, java.lang.Boolean>)
-LThing
(? super Thing
)和LThing
(Thing
)之间的细微差别使Dagger的类型不兼容。
我认为无法实现此目的,您需要定义一个单独的接口,该接口不具有与? super
相同的? extends
/ Function1
属性。
答案 2 :(得分:2)
正如Kiskae的回答中指出的那样,不可能使用kotlin来完成这项工作。您可以使用Java来使其工作:
@Module
public class DatabaseModuleJava {
@Provides
@Singleton
public Database provideDatabase(Application application, Function1<BetaFilterable, Boolean> betaFilter) {
return new Database(application, BuildConfig.VERSION_CODE, betaFilter);
}
@Provides
@Singleton
@SuppressWarnings("ConstantConditions")
public Function1<BetaFilterable, Boolean> provideBetaFiler() {
if (BuildConfig.FLAVOR_audience.equals("regular")) {
return betaFilterable -> !betaFilterable.getBetaOnly();
} else {
return betaFilterable -> true;
}
}
}