Hilt-注入接口实现的列表



让我展示一下我所说的代码的含义。

接口:

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>是否有效。

希望这能有所帮助!

相关内容

  • 没有找到相关文章