org.kodein.di.Kodein$NotFoundException: 找到 2 个与 bind() 匹配的绑定

org.kodein.di.Kodein$NotFoundException: 2 bindings found that match bind()

我有一个接口 WordsDataSource,我使用它实现了两个具体的 classes,即处理本地数据库的 WordsLocalDataSource 和另一个处理数据操作的 WordsRemoteDataSource在服务器上在线。问题是当我尝试使用 abstract class name WordsDataSource like

在存储库 class 中注入两个 classes
DefaultWordsRepository(
     private val wordsRemoteDataSource: WordsDataSource,
     private val wordsLocalDataSource: WordsDataSource) {

并在应用程序中添加依赖项class like

class WordsApplication : Application(), KodeinAware {

    override val kodein = Kodein.lazy {
        import(androidXModule(this@WordsApplication))
        bind() from singleton { WordsDatabase.getInstance(instance()) }
        bind<WordsDao>() with singleton { instance<WordsDatabase>().wordsDao() }
        bind() from singleton { WordsLocalDataSource(instance()) }
        bind() from singleton { WordsRemoteDataSource() }
        bind<WordsRepository>() with singleton { DefaultWordsRepository(instance(), instance()) }
        bind() from provider { ViewModelFactory(instance()) }
    }

然后在 运行 应用程序中,我在 logcat

中遇到以下问题
org.kodein.di.Kodein$NotFoundException: 2 bindings found that match bind<WordsDataSource>() with ?<WordsFragment>().? { ? }:
        bind<WordsLocalDataSource>() with singleton { WordsLocalDataSource }
        bind<WordsRemoteDataSource>() with singleton { WordsRemoteDataSource }

我已经通过简单地通过各自的具体 class 名称声明变量来尝试解决此问题,例如

DefaultWordsRepository(
     private val wordsRemoteDataSource: WordsRemoteDataSource,
     private val wordsLocalDataSource: WordsLocalDataSource) {

但是还是想知道有没有办法解决这个问题

我正在为 kodein 使用以下依赖项

implementation "org.kodein.di:kodein-di-generic-jvm:6.3.3"
implementation "org.kodein.di:kodein-di-framework-android-x:6.3.3"

您通过编写显式类型以正确的方式完成了它:

DefaultWordsRepository(
     private val wordsRemoteDataSource: WordsRemoteDataSource,
     private val wordsLocalDataSource: WordsLocalDataSource)

使用子类型时,我们无法知道选择哪种实现。写作

DefaultWordsRepository(
     private val wordsRemoteDataSource: WordsDataSource,
     private val wordsLocalDataSource: WordsDataSource)

如果您想要两种子类型或 WordsRemoteDataSourceWordsLocalDataSource 的两倍,则不会找不到。因此,您需要明确定义您的类型。甚至,我们可以将 WordsRemoteDataSource 放在 属性 wordsLocalDataSource 中,因为我们不能依赖变量名。