让我展示一下我所说的代码的含义。
接口:
interface MyInterface {
}
我有两个实现类:
@Singleton
class Implementation1 @Inject constructor(
private val gson: Gson,
) : MyInterface {
}
@Singleton
class Implementation2 @Inject constructor(
@ApplicationContext private val context: Context,
) : MyInterface {
}
我需要一个包含MyInterface
:实现列表的存储库类
@Singleton
class MyRepository @Inject constructor(
private val implementations: List<MyInterface>,
) {
}
问题部分:我正试图注入如下:
@InstallIn(SingletonComponent::class)
@Module
object MyDiModule {
@Provides
fun providesImplementations(
imp1: Implementation1,
imp2: Implementation2,
): List<MyInterface> {
return listOf(imp1, imp2)
}
}
但我得到编译错误:
/home/sayantan/AndroidStudioProjects/example/app/build/generated/hilt/component_sources/debug/com/example/ExampleApplication_HiltComponents.java:188: error: [Dagger/MissingBinding] java.util.List<? extends com.example.MyInterface> cannot be provided without an @Provides-annotated method.
public abstract static class SingletonC implements FragmentGetContextFix.FragmentGetContextFixEntryPoint,
^
有什么办法做到这一点吗?
我不知道这个答案有多正确,但它对我有效,所以作为答案发布。
这可以使用注释@JvmSuppressWildcards
来完成。
在上面的例子中,一切都很好,我只需要将这个注释添加到注入依赖项的类中,即MyRepository
类。
@JvmSuppressWildcards
@Singleton
class MyRepository @Inject constructor(
private val implementations: List<MyInterface>,
) {
}
我在我一直在做的项目中看到了同样的问题,但从List<gt;到数组<gt;似乎帮我搞定了。
所以在你的情况下,刀柄注射看起来像:
@Provides
fun providesImplementations(
imp1: Implementation1,
imp2: Implementation2,
): Array<MyInterface> {
return arrayOf(imp1, imp2)
}
然后与一起使用
@Singleton
class MyRepository @Inject constructor(
private val implementations: Array<MyInterface>,
) {
}
这可能会很晚,但我想放弃我的想法。
首先,您需要在模块类中注释@Provides
方法,因为dagger肯定会抛出MyInterface
的多个绑定的错误。
例如:
enum class ImplType {
Impl1, Impl2
}
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class ImplTypeAnnotation(val type: ImplType)
@Singleton
@Provides
@ImplTypeAnnotation(ImplType.Impl1)
fun provideImplementation1(impl1: Implementation1): MyInterface
// Do the same for Implementation2
其次,完成这些操作后,您需要将它们单独注入Repository类。例如
class MyRepository @Inject constructor(
@ImplTypeAnnotation(ImplType.Impl1) private val implementation1: MyInterface,
@ImplTypeAnnotation(ImplType.Impl2) private val implementation2: MyInterface
) {
// get the implementations as list here using Kotlin listOf()
}
注意:我不确定提供List<MyInterface>
是否有效。
希望这能有所帮助!