CJR*_*CJR 3 android kotlin dagger-2 android-jetpack dagger-hilt
我正在将Google I/O 的应用程序中的一些架构设计实现到我自己的应用程序中,但我在他们的应用程序中遇到了一些让我感到困惑的东西。
它们有一个带有存储库用例的域层,我通常在我的应用程序中使用它。但是,我确实必须在我的应用程序中为这些用例提供 dagger。但在 Google 的 I/O 应用程序上,我找不到任何提供这些用例的模块。当与注释 @HiltViewModel 的视图模型一起使用时(在我自己的应用程序中),它似乎有效?不知何故,这些被注入到我的视图模型中。我确实必须使用 Hilt 提供所有用例的依赖项(存储库等),但我不必通过 Hilt 提供任何用例。
这是它在我的代码中的外观示例。
用例:
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
}
Run Code Online (Sandbox Code Playgroud)
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)
}
}
Run Code Online (Sandbox Code Playgroud)
视图模型:
@HiltViewModel
class DetailViewModel @Inject constructor(
private val GetListUseCase: getListUseCase
): ViewModel() {
suspend fun getList(): Resource<ItemsList> {
getPokemonListUseCase.invoke(ListRequest(3))
}
}
Run Code Online (Sandbox Code Playgroud)
提供的存储库示例:
@Singleton
@Provides
fun provideRemoteRepository(
api: Api
): RemoteRepository = RemoteRepositoryImpl(api)
Run Code Online (Sandbox Code Playgroud)
远程仓库:
@ActivityScoped
class RemoteRepositoryImpl @Inject constructor(
private val api: Api
): RemoteRepository {
override suspend fun getList(request: ListRequest): PokemonList {
return api.getPokemonList(request.limit, request.offset)
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是: 这怎么行得通?为什么我不必通过 Hilt 提供用例?或者我的设计是错误的,即使这有效,我也应该通过 Hilt 提供用例?
编辑:
你的设计很棒!这并没有错,但是,如果您将用例放入单独的模块并根据您的需求确定范围,您可以为用例添加一些额外的上下文。模块的存在主要是为了当您确实有第三方依赖项(最简单的例子是 OkHTTPClient)或当您有接口 -> 接口的实现,或者您想要明显限制/扩展组件的生命周期/可见性时。
目前,您正在告诉 Hilt 如何通过使用 @Inject 注释其构造函数来提供 GetListUseCase 的实例,并且 Hilt 已经知道什么是“CoroutineDispatcher”(因为它是由协程模块中的 @Provides 提供的,对吧?)以及什么是 RemoteRepository(因为您正在注入接口,但在幕后您正在通过 @Provides 在 repo 模块中提供它的真正实现。
所以这就像说 - 给我一个具有两个构造函数依赖项的用例类实例,并且 Hilt 都知道它们,因此不会造成混淆。
如果您想要有一个作用域绑定/组件(如此处所述)或将您的用例标记为单例,那么您必须创建一个 UseCaseModule 并在那里定义您的用例组件的范围。
| 归档时间: |
|
| 查看次数: |
3467 次 |
| 最近记录: |