HBG
HBG

Reputation: 1771

Dagger2 @Binds methods' parameter type must be assignable to the return type with interface and implementation

I have a class that implements the interface java.util.function.Function that I'd like to inject for use in another class using Dagger2:

class MyUsefulClass @Inject constructor() : Function<List<String>, String> {

    override fun apply(lines: List<String>): String {
        // Do stuff 
        return ""
    }
}

Usually, I'd declare an @Binds declaration in the module class like so:

@Module
interface MyModule {

    @Binds
    fun provideMyUsefulClass(concretion: MyUsefulClass): Function<List<String>, String>
}

This approach has served me well for all the other classes I have in my project that implement this interface but in this one instance, I'm greeted by the error message:

@Binds methods' parameter type must be assignable to the return type…

What's funny is that changing the return type of the class and the @Binds declaration to Function<MutableList<String>, String> from Function<List<String>, String> works and everything compiles fine.

What am I missing here? The error message is clearly untrue. Is there some massive gotcha I'm unaware of here?

Upvotes: 9

Views: 13721

Answers (1)

al3c
al3c

Reputation: 1452

I suspect this might be a case of "missing" @JvmSuppressWildcards, whereby kotlin adds some ? extends String in the List type and that makes the dagger compiler fail (the error message should contain some more hints).

I guess you need to change your function type to Function<List<@JvmSuppressWildcards String>, String> where you use it.

It's a known annoyance, you can read something more in detail here: https://medium.com/@naturalwarren/dagger-kotlin-3b03c8dd6e9b

I suspect that MutableList doesn't have that problem because you can both 'read' and 'write' strings with it.

Upvotes: 15

Related Questions