Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Please use override option or check for definition, koin android?

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?

like image 703
WISHY Avatar asked Jun 02 '20 06:06

WISHY


People also ask

What is KOIN for Android developers?

In this blog, we are going to learn about Koin, a new dependency injection framework for Android Developers. If you are not familiar with why we need a dependency injection framework in our project, click here.

What does the name parameter do in KOIN?

The name parameter is used to override the default name that Koin gives each bean definition. By default, Koin uses the module path combined with the class name, i.e. first_module.second_module.ClassName. If there are no module paths, Koin defaults to just the beans Class Name. For example:

How to define a module in KOIN?

To define a module use the module block and declare the dependencies inside of it: Now let’s initialize Koin! In case the project don’t have a custom Application class, you will need to create one and declare it in your manifest file.

What is the default name of a KOIN class?

If there are no module paths, Koin defaults to just the beans Class Name. For example: In the example above the default name is used for the first definition, you can decide to not pass a name parameter to the get function, as that is what its default implementation.


2 Answers

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
    }
  }
)
like image 190
V Mircan Avatar answered Oct 20 '22 11:10

V Mircan


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(networkCall: NetworkCall) : ViewModel(){
 var networkCall: NetworkCall;
init {
    this.networkCall = networkCall
}
}

So far I feel koin is quite good

like image 45
WISHY Avatar answered Oct 20 '22 11:10

WISHY