Deepanshu tyagi
Deepanshu tyagi

Reputation: 44

Using koin in Multi-module application

Hi in a multi modules app, I am loading child modules using loadKoinModules() and unloading it using unloadKoinModules() in feature module my code looks like

class FeatureActivity:AppCompatActivity(){
    private val loadFeatures by lazy { loadKoinModules(featureModule) }
    private fun injectFeatures() = loadFeatures

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        injectFeatures()
    }

   override fun onDestroy() {
        super.onDestroy()
        unloadKoinModules(featureModule)
    }
} 

Everything works fine but problem start when another instance on same activity is loaded. While current activity is in background. App crash due to error below

org.koin.error.BeanOverrideException:  Try to override definition with Factory

Is there a way to avoid this error

Upvotes: 1

Views: 6374

Answers (3)

gmetax
gmetax

Reputation: 3973

It is somehow correct what you are doing, you can unload dynamically as you do this is why unloadKoinModules has been added link

but why aren't you unloading onStop? according to android lifecycle and what you want to do, you have to unload in onStop

When activity gets focus onCreate will occur (and you will load modules), later when activity loses focus, onStop will occurs (and you will unload modules) and the circle between the events...

enter image description here

class FeatureActivity:AppCompatActivity(){
    private val loadFeatures by lazy { loadKoinModules(featureModule) }
    private fun injectFeatures() = loadFeatures

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        injectFeatures()
    }

   override fun onStop() {
        super.onStop()
        unloadKoinModules(featureModule)
    }
} 

Upvotes: 6

Ibrahim Ali
Ibrahim Ali

Reputation: 1297

Koin won't let to you redefine an already existing definition (type,name,path …​). You will run into an error.

You need to allow definition override :-

val featureModule = module {

    // override for this definition
    single<yourType>(override=true) { YourClass() }
}

ALSO you can override on module level instead of overriding on definition level only:-

val featureModule = module(override=true) {

    single<yourType> { YourClass() }
}

Important:- Order matters when listing modules and overriding definitions. You must have your overriding definitions in last of your module list.

Upvotes: 3

laalto
laalto

Reputation: 152817

Some possibilities:

  • Load your feature module in the top-level application level and don't scope it to any activity lifecycle.

  • Add a reference-counting wrapper around your module load/unload so the module is not reloaded if it is already loaded, and it is only unloaded when the usage count is zero. (You can simplify this by not caring about unloading and change the count to just a "initialised" boolean.)

Upvotes: 1

Related Questions