Search code examples
androiddependency-injectionviewmodelandroid-architecture-componentskoin

When KOIN graph reassembling, delegate function viewmodel() not refreshing viewmodel instance


we are using in our project KOIN like DI library.

in some cases, when ViewModel instance not refreshing when Koin context is killing and recreating again. We need to implement feature like 'reassembling dependency graph in runtime', and this issue very critical for us.

I have ViewModel module like this:

object ViewModelModule {
    val module by lazy {
        module {
            viewModel { AppLauncherViewModel(get(), get(), get(), get()) }           
            viewModel { AuthLoginPasswordViewModel(get(), get()) }
            viewModel { SettingsViewModel(get(), get()) }
            // some others
        }
    }
}

And my graph is assembling in android application by this way:

    private fun assembleGraph() {
        val graph = listOf(
                AppModule.module,
                StorageModule.module,
                DatabaseConfigModule.module,
                RepositoryModule.module,
                InteractorModule.module,
                ViewModelModule.module
        )

        application.startKoin(application, platformGraph)
    }

    fun reassembleGraph() {
        stopKoin()
        assembleGraph()
    }

And when reassembleGraph() is calling - all good, another instances in graph are refreshing, but ViewModels, that injected in activity - are not, and they are keeping old references. I guess, that viewmodel is attached to activity lifecycle, and could help activity recreation, but i think it's not the best solution.

Has anyone the same problems? And help me please with advice, how to solve it, please.


Solution

  • You can do it with the use of scope in KOIN.

    1) Define your ViewModels in scope

    scope(named("ViewModelScope")){
        viewModel {
            AppLauncherViewModel(get(), get(), get(), get())
            AuthLoginPasswordViewModel(get(), get())
            SettingsViewModel(get(), get())
        }
    }
    

    2) Create that particular scope with the use of below line in your application class.

    val viewModelScope = getKoin().getOrCreateScope("ViewModelScope")
    

    Above code is used to get ViewModel. And when you want to recreate scope you just need to close scope and recreate again. To close scope use below code.

    val viewModelScopeSession = getKoin().getOrCreateScope("ViewModelScope")
    viewModelScopeSession.close()
    

    Once the scope is closed then after whenever you request to create or get scope at that time it will return new instance as per your requirement.

    For further reference, you can see below link (8th Point).

    Koin documentation