I have an interface WordsDataSource
using which I have implemented two concrete classes namely WordsLocalDataSource
that deals with local database and another WordsRemoteDataSource
that deals with manipulating data online on the server. The problem is when I try to inject the two classes in repository class using abstract class name WordsDataSource
like
DefaultWordsRepository(
private val wordsRemoteDataSource: WordsDataSource,
private val wordsLocalDataSource: WordsDataSource) {
And adding dependencies in Application 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()) }
}
Then upon running the app I encounter the following issue in the 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 }
I have tried the workaround for this by simply declaring the variables by their respective concrete class names like
DefaultWordsRepository(
private val wordsRemoteDataSource: WordsRemoteDataSource,
private val wordsLocalDataSource: WordsLocalDataSource) {
But still want to know whether or not is there any way to resolve the issue.
I am using the following dependencies for kodein
implementation "org.kodein.di:kodein-di-generic-jvm:6.3.3"
implementation "org.kodein.di:kodein-di-framework-android-x:6.3.3"
You have done it the right way by writing the explicit types:
DefaultWordsRepository(
private val wordsRemoteDataSource: WordsRemoteDataSource,
private val wordsLocalDataSource: WordsLocalDataSource)
When working with sub-types we cannot know what kind of implementation to choose. Writing
DefaultWordsRepository(
private val wordsRemoteDataSource: WordsDataSource,
private val wordsLocalDataSource: WordsDataSource)
Doesn't cannot find if you want both sub-types or twice the WordsRemoteDataSource
or WordsLocalDataSource
. Thus, you need to explicit define your types. Even, we could put WordsRemoteDataSource
in the property wordsLocalDataSource
, as we cannot rely on variable names.