I've got a interface with a couple of implementations:
interface PuNoManager {
fun notifyUser(userId: Int)
}
class FcmManager
@Inject
constructor(val fcmClient: FcmClient) : PuNoManager {
override fun notifyUser(userId: Int) { ... }
}
class ApnsManager
@Inject
constructor(val apnsClient: ApnsClient) : PuNoManager {
override fun notifyUser(userId: Int) { ... }
}
Which are both bound in my Module
, along with a @Provides
-annotated method to get a List<PuNoManager>
:
class PuNoModule: AbstractModule() {
override fun configure() {
bind(ApnsManager::class.java)
bind(FcmManager::class.java)
}
@Provides
fun puNoManagers(apnsManager: ApnsManager, fcmManager: FcmManager): List<PuNoManager> {
return listOf(apnsManager, fcmManager)
}
}
The problem arises when I have a class that needs the List<PuNoManager>
—Guice complains that the type hasn't been bound:
Explicit bindings are required and java.util.List<? extends ...PuNoManager> is not explicitly bound.
while locating java.util.List<? extends ...PuNoManager>
I know my Guice setup is working, as I previously had just the ApnsManager
and am adding the second PuNoManager
, FcmManager
. The problem stems from the dependent class requesting injection of List<PuNoManager>
instead of just ApnsManager
.
List<X>
in Kotlin is translated to java.util.List<? extends X>
on the JVM. Apparently, Guice doesn't support injection of such values. To avoid the wildcard here, you can use a MutableList<X>
instead, which translates to java.util.List<X>