I am refactoring my app for DI with Hilt, and before I had a ViewModel instantiating the RoomDatabase to get the DAO and pass it to the repository. The .getDatabase method has a CoroutineScope parameter for launching a coroutine inside the .RoomDatabase.Callback() to populate the database asynchronously.
class MyViewModel(application: Application) : AndroidViewModel(application) {
init {
val dao = MyDB.getDatabase(
application,
viewModelScope //using viewModelScope inside the ViewModel
).myDAO()
repository = MyRepository(dao)
}
}
abstract class MyDB : RoomDatabase() {
abstract fun myDAO(): MyDAO
private class MyDatabaseCallback(private val scope: CoroutineScope) : RoomDatabase.Callback() {
...
}
Now with Hilt the DB will be instantiated in a Module installed in the SingletonComponent:
@Module
@InstallIn(SingletonComponent::class)
object DBModule {
@Provides
fun provideDao(@ApplicationContext applicationContext: Context) : MyDAO {
return MyDB.getDatabase(
applicationContext,
scope // What CoroutineScope to use here ???
).myDAO
}
@Provides
fun provideRepository(dao: MyDAO) = MyRepository(dao)
}
What's the best scope to use in this case, as viewModelScope cannot be used anymore? And how to reference it? Ideally an ActivityRetained scoped one, so it's not scoped to the entire application, but it will survive Activity restarts (i.e. configuration changes, etc)
Thank you in advance.
I hope It helps with your use case.
// You will have to use hilt with viewModel as well in order to used below function further more I don't recomment to used that as
// ViewModelScop strick inside viewModel. If It comes to database then It should not restrict to viewModel Infact database is a component which
// Provide service to each part of the application so use Simple Coroutine scope...
// Incase something goes wrong and your activity kills/destoryed then the opertaion get stoped because of viewModelScope
@Provides
fun provideCorountineScope(viewModel: MyViewModel): CoroutineScope {
return viewModel.viewModelScope
}
@Singleton
@Provides
fun providesCoroutineScope(): CoroutineScope {
// Run this code when providing an instance of CoroutineScope
return CoroutineScope(SupervisorJob() + Dispatchers.IO)
}
@Singleton
@Provides
fun provideDao(@ApplicationContext applicationContext: Context, scope: CoroutineScope) : MyDAO {
return MyDB.getDatabase(
applicationContext,
scope
).myDAO
}