【问题标题】:Dagger Hilt Missing/Binding interface with generics带有泛型的 Dagger Hilt 缺失/绑定接口
【发布时间】:2023-03-26 21:11:01
【问题描述】:

我正在使用 Dagger Hilt 来提供应用程序中的依赖项。我有以下类来实现用例:

BaseUseCase.kt

interface BaseUseCase<in Parameter, out Result> {
    suspend operator fun invoke(params: Parameter): Result
}

UseCasesModule.kt

@Module
@InstallIn(ViewModelComponent::class)
object UseCasesModule {

    @Provides
    fun provideGetUseCase(
        repositoryImpl: RepositoryImpl
    ): GetUseCase {
        return GeUseCase(repositoryImpl as Repository>)
    }
}

GetUseCase.kt

typealias GetBaseUseCase = BaseUseCase<GetUseCase.Params, Flow<ResultWrapperEntity<List<ModelItem>>>>

class GetUseCase(
    private val repository: Repository
) : GetBaseUseCase {

    override suspend fun invoke(params: Params) =
        repository.get(params.id)

    data class Params(
        val id: Long
    )
}

当我尝试在视图模型中使用 GetBaseUseCase 的抽象时,问题就来了:

@HiltViewModel
class ListViewModel @Inject constructor(
    private val useCase: GetUseBaseCase
) : ViewModel()

但如果我像这样注入 GetUseCase 实现,它工作正常:

@HiltViewModel
class ListViewModel @Inject constructor(
    private val useCase: GetUseCase
) : ViewModel()

我收到以下错误:

AppClass_HiltComponents.java:131: error: [Dagger/MissingBinding] com.....BaseUseCase<? super com.....GetUseCase.Params,? extends kotlinx.coroutines.flow.Flow<? extends com.....ResultWrapperEntity<? extends java.util.List<com......ItemModel>>>> cannot be provided without an @Provides-annotated method.

公共抽象静态类SingletonC实现AppClass_GeneratedInjector,

我试图在刀柄的模块中返回 GetBaseUseCase 的抽象,但我得到了同样的错误。

【问题讨论】:

    标签: android dependency-injection dagger dagger-hilt


    【解决方案1】:

    你可以构造函数注入你的GeUseCaseimplementation,然后bindinterface

    原因是匕首不知道如何获取GetBaseUseCase的实例

    类似

    @Singleton // without any scope or with any other scope
    class GetUseCase @Inject constructor(
        private val repository: Repository
    ) : GetBaseUseCase {
    
        override suspend fun invoke(params: Params) =
            repository.get(params.id)
    
        data class Params(
            val id: Long
        )
    }
    

    然后将其与您的界面绑定

    @Module
    @InstallIn(ViewModelComponent::class)
    interface SomeModule {
      @Binds
      fun bind(usecase: GetUseCase): BaseUseCase<,> (your generic type)
    }
    

    它应该也适用于泛型 - 这是您遇到任何问题的线索

    https://github.com/google/dagger/issues/2161

    如果不能进行构造函数注入 - 你可以提供然后绑定

    @Module
    @InstallIn(ViewModelComponent::class)
    abstract class YourModule {
    
        @Binds
        abstract fun bind(usecase: GetUseCase): BaseUseCase<,> (your generic type)
    
        companion object {
    
            @Provides
            fun providesUseCase(): GetUseCase {
                return GetUseCase(// required dependency)
            }
        }
    }
    

    您还需要添加@JvmSuppressWildcards - 以避免您收到@Binds methods' parameter type must be assignable to the return type 的错误

    这里是更多信息的链接

    https://github.com/google/dagger/issues/1143#issuecomment-381776533

    【讨论】:

    • 我无法使用“@Inject 构造函数”,因为它们位于没有 dagger 依赖项的模块中
    • 我也收到了@Binds方法@Binds methods' parameter type must be assignable to the return type的以下错误@
    • 如果没有注入构造函数 - 您可以提供然后将其与接口绑定。更新了答案。
    • 还是有错误@Binds methods' parameter type must be assignable to the return type
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    相关资源
    最近更新 更多