Reputation: 173
I have a repository that should be Singletone as it holds state inside it. I provide it like this:
@Module
@InstallIn(SingletonComponent::class)
object RepoModule {
@Provides
fun provideMyRepository(/* Deps */): MyRepository = MyRepositoryImpl( /* Deps */ )
}
And there is a UseCase that is only used in some ViewModel and I want it to live as long as ViewModel does. So I want create it as ViewModelComponent:
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule {
@Provides
fun provideMyUseCase(myRepo: MyRepository): MyUseCase = MyUseCase(myRepo=myRepo)
}
The problem is that I cannot create this UseCase as ViewModelComponent because it should have the same Component as all its dependencies do. So if MyRepository is provided as Singletone, MyUseCase should be provided the same way.
How can I handle this problem? I can just make MyUseCase singlotone too and Hilt will build the project, but I don't want MyUseCase to exist all the time application lives.
Upvotes: 0
Views: 36
Reputation: 4276
Both of your bindings are actually unscoped. Per hilt docs:
Warning: A common misconception is that all bindings declared in a module will be scoped to the component the module is installed in. However, this isn’t true. Only bindings declarations annotated with a scope annotation will be scoped.
So you should add scoping annotations to the providing methods:
@Provides
@Singleton
fun provideMyRepository(/* Deps */): MyRepository = MyRepositoryImpl( /* Deps */)
and
@Provides
@ViewModelScoped
fun provideMyUseCase(myRepo: MyRepository): MyUseCase = MyUseCase(myRepo = myRepo)
So if MyRepository is provided as Singletone, MyUseCase should be provided the same way.
Why? You can provide MyUseCase
per ViewModel
with the same singletone MyRepository
instance.
Also, if all of the MyUseCase
dependencies are provided by Hilt, you can avoid using a Module by using constructor based injection:
@ViewModelScoped
class MyUseCase @Inject constructor(
val myRepo: MyRepository,
) {
}
Upvotes: 0