I'm injecting a viewModelScope into my repository....
# dagger
s
I'm injecting a viewModelScope into my repository. But, since I'm injecting the repository into the view model, it becomes a cyclic dependency. How can I fix this?
Copy code
@HiltViewModel
class MyViewModel @Inject constructor(
    private val repository: MyRepository
) : ViewModel()

class MyRepository(
    private val api: MyApi,
    private val coroutineScope: CoroutineScope
)
Module:
Copy code
@InstallIn(ViewModelComponent::class)
@Module
object RepositoryModule {

    @Provides
    fun provideMyRepository(
        api: MyApi,
        viewModel: MyViewModel
    ): MyRepository {
        return MyRepository(api, viewModel.viewModelScope)
    }
}
j
Not injecting the viewModel/viewModelScope in the repo
3
just use suspend funs if in the repo/api
1
d
Create a custom scope with dispatchers.main.immediate and a supervisor job, then inject that
s
@Daniel I'll try that
@Javier I want to create a StateFlow in my repo
j
why you need the scope?
myStateFlow.value doesn't need even being async (if so, just suspend fun)
if you want a suspend fun to use a specific dispatcher, just use
Copy code
suspend myFancySuspendFun() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) { ... }
s
I'm doing this:
flow { }.stateIn(scope, ...)
j
ah, I understand
s
Yeah anyways I'm creating the StateFlow in view model now
j
you are exposing room flow or something so?
I would do that indeed, just expose a normal flow, and collect it in the viewModel and emit whatever you need as state in the stateFlow in the VM
👍 1
s
I'm fetching data from the network and exposing
Flow<Resource>
for loading, success and error states
👍 1
s
I inject a app-wide coroutine scope into any singleton component needing to launch coroutines
Copy code
@Provides
@Singleton
@GlobalScope
fun provideGlobalScope(): CoroutineScope = MainScope()
Copy code
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(
    AnnotationTarget.CLASS,
    AnnotationTarget.FIELD,
    AnnotationTarget.FUNCTION,
    AnnotationTarget.VALUE_PARAMETER
)
annotation class GlobalScope
as long as you do not inject this into anything with a lifecycle or cancel it, it will be fine