11

I am implementing Koin DI in my android application. I was successfully able to create some of the modules. However I got an exception where I tried to get object from another in module.

These are my modules

val networkModule = module {
factory { provideRetrofit() }

single { provideNetworkApi(get()) }
}


fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
    .baseUrl(NetworkConstant.BASE_URL)
    .addConverterFactory(
        GsonConverterFactory.create(
            GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .create()
        )
    )
    .client(OkHttpClient.Builder().build())
    .build()

 }

fun provideNetworkApi(retrofit: Retrofit): NetworkCall =
retrofit.create(NetworkCall::class.java)

view model module - i want to pass the network call object here

val viewModelModule = module {
single { provideNetworkApi(get ()) }
}

This is my code in application class

startKoin {
        androidLogger()
        androidContext(this@BaseApp)
        modules(listOf(networkModule,viewModelModule))
    }

This is the exception I get

java.lang.RuntimeException: Unable to create application com.mountmeru.BaseApp: org.koin.core.error.DefinitionOverrideException: Definition '[Factory:'com.mountmeru.network.NetworkCall']' try to override existing definition. Please use override option or check for definition '[Factory:'com.mountmeru.network.NetworkCall']'
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6465)
    at android.app.ActivityThread.access$1300(ActivityThread.java:219)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 Caused by: org.koin.core.error.DefinitionOverrideException: Definition '[Factory:'com.mountmeru.network.NetworkCall']' try to override existing definition. Please use override option or check for definition '[Factory:'com.mountmeru.network.NetworkCall']'
    at org.koin.core.scope.ScopeDefinition.save(ScopeDefinition.kt:25)

Any clue whats wrong here?

WISHY
  • 11,067
  • 25
  • 105
  • 197
  • replace `single { provideNetworkApi(get ()) }` to `single {provideNetworkApi(provideRetrofit()) }` and try. – Jaymin Jun 02 '20 at 06:40

2 Answers2

10

For anyone else dealing with this error message, Koin disallows any ambiguity in its modules. So if you try to load one bean definition that conforms to the same signature as one that has already been loaded, you end up getting this error. If your intention is to replace the old definition with a new one, then use the override flag.

Here is a usage example:

loadKoinModules(
  module(override = true) {
    single<A> {
      A
    }
  }
)
V Mircan
  • 203
  • 5
  • 13
1

I was doing it all wrong. The correct implementation is

I wanted the NetworkCall object in my LoginViewModel

val viewModelModule = module {
single { LoginViewModel(get()) }
}

And the viewmodel class is follows

class LoginViewModel(val networkCall: NetworkCall) : ViewModel(){

}

So far I feel koin is quite good

Asad Mahmood
  • 532
  • 1
  • 5
  • 15
WISHY
  • 11,067
  • 25
  • 105
  • 197