Koin Dependency Injection - org.koin.core.error.NoBeanDefFoundException

1.9k Views Asked by At

Hello I am working on Android app development and in it a koin dependency injection library is integrated. It is something like below:

object Jaimin {
   fun initJaimin(
        application : Application,
        listOf : List<Module>? = null
    ) {


        var moduleList = listOf(
            jaiminAppModelModule, jaiminBleNetworkModule,
            jaiminViewModelModule, databaseModule,jaiminRepositoryModule
        )

        listOf?.forEach {
            moduleList = moduleList + it
        }

        startKoin {
            androidLogger(if (BuildConfig.DEBUG) Level.ERROR else Level.NONE)
            androidContext(application)
            modules(
                moduleList
            )
        }

    }

You can check startKoin is implemented there. I am getting error here in this module:

val jaiminRepositoryModule = module {
    single {
        JaiminRepository(get(),get())
    }
}

Error:

Instance creation error : could not create instance for [Singleton:'com.jaimin.sdk.repository.JaiminRepository']: org.koin.core.error.NoBeanDefFoundException: |- No definition found for class:'com.jaimin.api.RemoteDataSource'. Check your definitions! org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:287) org.koin.core.scope.Scope.resolveValue(Scope.kt:257)

What might be the issue?

Edit: Below is the constructor for JaiminRepository class:

  class JaiminRepository constructor(
    private var remoteDataSource : RemoteDataSource,
    private var enrollApiInterface : EnrollApiInterface
) {

and

Below is the constructor for JaiminViewModel class:

class JaiminViewModel(application : Application, private var jaiminRepository: JaiminRepository) :
    AndroidViewModel(application) {
    var jaiminEnroll : MutableLiveData<JaiminEnroll> = MutableLiveData()
    var error : MutableLiveData<String> = MutableLiveData()
    var inputUserID : ObservableField<String> = ObservableField("")
    var isLoading : ObservableField<Boolean> = ObservableField(false)

and inside ViewModelModule.kt :

  viewModel {
       JaiminViewModel(get(),get())
    }
1

There are 1 best solutions below

7
On

Your biggest issue is that you're not providing definitions correctly.

When you write get(), that means Koin tries to find relevant dependency for that given scope. If it’s not able to find it, then you'll get error org.koin.core.error.NoBeanDefFoundException.

If you look closely to given error:

Instance creation error : could not create instance for [Singleton:'com.jaimin.sdk.repository.JaiminRepository']: org.koin.core.error.NoBeanDefFoundException: |- No definition found for class:'com.jaimin.api.RemoteDataSource'. Check your definitions! org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:287) org.koin.core.scope.Scope.resolveValue(Scope.kt:257)

You'll see that it gives error on RemoteDataSource, hence it was not able to find relevant dependency for that.


The solution is to resolve those dependencies via definitions.

Here's how your DI for repository should look like:

val jaiminRepositoryModule = module {

    factory {
        RemoteDataSource()
    }

    factory<EnrollApiInterface> {
        // Your bean definition for EnrollApiInterface since you can't create objects for interface
    }
    
    single {
        JaiminRepository(get(), get())
    }
}

Same goes for view model dependency:

viewModel {
   JaiminViewModel(androidContext(), get()) // Here, android context can be used to inject application class
}