InsertKoinIO / koin

Koin - a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform
https://insert-koin.io
Apache License 2.0
9.09k stars 719 forks source link

Scope objects to viewmodel lifecycle #1080

Closed ChristopherME closed 2 years ago

ChristopherME commented 3 years ago

I have the following situation. There are some objects I would like to instantiate only ONCE for the whole lifetime of my viewmodel. Something like @InstallIn(ViewModelComponent::class) does in dagger-hilt.

The following koin module is prepared for provide an instance of a viewmodel which is going to be injected into a fragment. The fragment can be replaced and added to the backstack (the viewmodel can survive the replace transaction).

val featureMoviesModule = module {

    factory { provideMoviesService(retrofit = get()) }

    factory<MoviesRemoteDataSource> {
        MoviesRemoteDataSourceImpl(
            connectivityUtils = get(),
            ioDispatcher = get(named("ioDispatcher")),
            errorParserAdapter = get(),
            movieService = get()
        )
    }

    /**
     * This is not so optimal due to viewModel is requiring also the mapper,
     * Therefore a new instance on MovieMapper is going to be created.
     * We ended up with 2 instances of MovieMapper.
     */
    factory<MovieMapper> { MovieMapperImpl(defaultDispatcher = get(named("defaultDispatcher"))) }

    factory<MoviesRepository> { MoviesRepositoryImpl(remoteDataSource = get(), mapper = get()) }

    viewModel { MovieListViewModel(moviesRepository = get(), mapper = get()) }

}

With this configuration I ended up with two MovieMapperImpl() instances, which is bad.

Describe the solution you'd like Some clear explanation of how to scope some items to the same lifetime of my viewmodel.

Describe alternatives you've considered Single works but I dont want a singleton instance for a mapper that is used only in one specific feature.

Target Koin project Im currently using koin 3.0.1

scottkruse commented 3 years ago

Any update on this? @ChristopherME

ChristopherME commented 3 years ago

0 updates about it @scottkruse ...

scottkruse commented 3 years ago

@ChristopherME I hacked around this but doesn't feel great.

module { viewModel { val sharedComponent = get<SharedComponent>() ExampleViewModel( get { parametersOf(sharedComponent) } ) } factory { (sharedComponent: SharedComponent) -> OtherComponent(sharedComponent) } }

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.