I am implementing some of the architectural designs from Google I/O's app to my own app, but I have come across something in their app that has created some confusion for me.
They have a domain layer with repository usecases, which I use myself in my apps usually. However, I do have to provide these usecases with dagger in my app. But on Google's I/O app, I cannot find any module that provides these usecases. And when used with viewmodels annotated @HiltViewModel (In my own app), it seems like it works? Somehow these get injected into my viewmodels. I do have to provide all the usecase's dependencies(repositories etc) with Hilt, but I don't have to provide any usecase via Hilt.
Here is example how it looks in my code.
Usecase:
abstract class UseCase<in P, R>(private val coroutineDispatcher: CoroutineDispatcher) {
suspend operator fun invoke(parameters: P): Resource<R> {
return try {
withContext(coroutineDispatcher) {
execute(parameters).let {
Resource.Success(it)
}
}
} catch (e: Exception) {
Timber.d(e)
Resource.Error(e.toString())
}
}
@Throws(RuntimeException::class)
protected abstract suspend fun execute(parameters: P): R
}
Concrete implementation of usecase:
class GetListUseCase @Inject constructor(
private val coroutineDispatcher: CoroutineDispatcher,
private val remoteRepository: RemoteRepository
): UseCase<ListRequest,ItemsList>(coroutineDispatcher) {
override suspend fun execute(parameters: ListRequest): ItemsList{
return remoteRepository.getList(parameters)
}
}
Viewmodel:
@HiltViewModel
class DetailViewModel @Inject constructor(
private val GetListUseCase: getListUseCase
): ViewModel() {
suspend fun getList(): Resource<ItemsList> {
getPokemonListUseCase.invoke(ListRequest(3))
}
}
Example of provided repo:
@Singleton
@Provides
fun provideRemoteRepository(
api: Api
): RemoteRepository = RemoteRepositoryImpl(api)
Remote repo:
@ActivityScoped
class RemoteRepositoryImpl @Inject constructor(
private val api: Api
): RemoteRepository {
override suspend fun getList(request: ListRequest): PokemonList {
return api.getPokemonList(request.limit, request.offset)
}
}
My Question is: How come this works? Why don't I have to provide usecase' via Hilt? Or is my design wrong and I should provide usecases via Hilt even if this works?
EDIT:
Link to Google I/O domain layer and ui layer if it helps.
from Provide domain-layer UseCase classes with HILT
No comments:
Post a Comment