3

I can't call inject from constructor for my project via Koin DI.

If I use "... by inject()" for injection the DataRepository class, all works perfectly. But I want to provide inject in a constructor of a class.

I have a crash in the CounterPresenter class in "repo.addPayment(payment)" line. Look down the page.

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964) 
 Caused by: org.koin.error.NoBeanDefFoundException: No compatible definition found. Check your module definition

Here is my structure:

enter image description here

Koin DI Please, how I can change this module for successful working?

val repositoryModule = module {
    single { PrefsManager() }
    single<IRepository> { DataRepository(get() as LocalRepository) }
    single<ILocalRepository> { LocalRepository(get()) }
}

val databaseModule = module {
    single {
        Room.databaseBuilder(androidApplication(), AppDatabase::class.java, Enviroment.DATABASE_NAME).build()
    }
    single { get<AppDatabase>().getCounterDao() }
}

val presentersModule = module {
    factory { CounterPresenter() }
    factory { SplashPresenter() }
}

class DataRepository

class DataRepository(private val localRepository: ILocalRepository) : IRepository {

    init {  Log.d("ROMAN", "init DataRepository") }

    override suspend fun addPayment(payment: Int) {
        localRepository.addPayment(payment)
    }
}

class LocalRepository

class LocalRepository(private val counterDao: CounterDao) : ILocalRepository {

    override suspend fun addPayment(payment: Int) = runBlocking {
        counterDao.insertPayment(Payment(payment))
    }
}

class CounterPresenter

class CounterPresenter : BasePresenter<CounterContract.View>(), CounterContract.Presenter {
    private val repo: DataRepository by inject()


    override fun onViewCreated() {
        super.onViewCreated()
        launchIO { repo.addPayment(payment) }
    }
  • pls provide detailed stacktrace: Koin typically shows much more than just "no compatible definition found" – nyarian Apr 08 '19 at 14:30

1 Answers1

4

To inject dependencies to any class, the class must implement KoinComponent interface.(except Activity and Fragments)

Do this and your code should be working:

class CounterPresenter : BasePresenter<CounterContract.View>(), CounterContract.Presenter, KoinComponent {
    private val repo: DataRepository by inject()


    override fun onViewCreated() {
        super.onViewCreated()
        launchIO { repo.addPayment(payment) }
    }
}
Birju Vachhani
  • 6,072
  • 4
  • 21
  • 43
  • Worked for me. I was trying to inject an instance of dao into a repository class. Just added KoinComponent and changed the import, it worked. – Tarsila Costalonga Feb 28 '21 at 18:27