Dagger Hilt Missing/Binding 与泛型的接口
Dagger Hilt Missing/Binding interface with generics
我正在使用 Dagger Hilt 在应用程序中提供依赖项。我有以下 classes 来实现用例:
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.
public 抽象静态 class SingletonC 实现 AppClass_GeneratedInjector,
我已经尝试 return 刀柄模块中 GetBaseUseCase 的抽象化,但我遇到了同样的错误。
您可以构造函数注入您的 GeUseCase
implementation
然后 bind
interface
。
因为 dagger 不知道如何获取 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
的错误
这里是link了解更多信息
https://github.com/google/dagger/issues/1143#issuecomment-381776533
我正在使用 Dagger Hilt 在应用程序中提供依赖项。我有以下 classes 来实现用例:
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.
public 抽象静态 class SingletonC 实现 AppClass_GeneratedInjector,
我已经尝试 return 刀柄模块中 GetBaseUseCase 的抽象化,但我遇到了同样的错误。
您可以构造函数注入您的 GeUseCase
implementation
然后 bind
interface
。
因为 dagger 不知道如何获取 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
这里是link了解更多信息
https://github.com/google/dagger/issues/1143#issuecomment-381776533