I have a Kotlin class similar to this:
class MyClass @Inject constructor(val work: (Int) -> Unit)) { ... }
Neither the bind
nor the @Provides
is working:
class FunctionModule : AbstractModule() {
override fun configure() {
bind(object : TypeLiteral<Function1<Int, Unit>>() {}).toInstance({})
}
@Provides
fun workFunction(): (Int) -> Unit = { Unit }
}
}
I keep getting the error:
No implementation for kotlin.jvm.functions.Function1< ? super java.lang.Integer, kotlin.Unit> was bound.
How can I inject an implementation for a Kotlin function using Guice?
tl;dr - Use:
bind(object : TypeLiteral<Function1<Int, @JvmSuppressWildcards Unit>>() {})
.toInstance({})
In the class
class MyClass @Inject constructor(val work: (Int) -> Unit)) { ... }
the parameter work
has a type (as least according to Guice) of:
kotlin.jvm.functions.Function1<? super java.lang.Integer, kotlin.Unit>
However,
bind(object : TypeLiteral<Function1<Int, Unit>>() {}).toInstance({})
registers a type of kotlin.jvm.functions.Function1<? super java.lang.Integer, **? extends** kotlin.Unit>
Changing bind
to bind(object : TypeLiteral<Function1<Int, **@JvmSuppressWildcards** Unit>>() {}).toInstance({})
to remove the variance on the return type allows Guice to properly inject the function.