Search code examples
javaandroidkotlindagger-2dagger

Why the dagger graph works works in java but in Kotlin it says missing Provides when I have provided?


I have some issues when converting dagger interfaces from java to Kotlin

I got [Dagger/MissingBinding] java.util.Map cannot be provided without an @Provides-annotated method.

Here is my interface

   interface TopicConfigModule {
    @Binds
    @IntoMap
    @StringKey(NAME)
    fun bindCommandHandler(handler: TopicCommandHandler): CommandHandler

    companion object {
        @JvmStatic
        @Provides
        @FragmentScope
        fun provideHubsConfig(
            commandRegistry: Map<String, CommandHandler>
        ): Config {
            return ...
        }
    }
}

and CommandHandler is java interface

public interface HubsCommandHandler {```}



Solution

  • Map in Kotlin is covariant (variance) on its value type (public interface Map<K, out V>), but Map in Java is not. Your function will be translated to

    Config provideHubsConfig(Map<String, ? extends CommandHandler> commandRegistry) { ... }
    

    but dagger provides exactly Map<String, CommandHandler>. So we need to suppress wildcards with @JvmSuppressWildcards

    commandRegistry: Map<String, @JvmSuppressWildcards CommandHandler>
    

    Calling Kotlin from Java - variant-generics