Android Dagger-Hilt 如何在抽象中进行字段注入class?

Android Dagger-Hilt How to do Field Injection in abstract class?

我正在使用 Dagger-Hilt 进行依赖注入,但我不知道如何在抽象中进行字段注入 class。

// @ViewModelScoped
abstract class BaseUseCase<Params, Return>{
    // lateinit var not initiazlied. Cannot be injected
    @Inject
    lateinit var errorHandler: ErrorHandler

    fun execute(@nullable params: Params?=null): Flow<DataState<Return>> = flow {
        emit(Datastate.Loading)
        emit(executeRealization(params))
        ...
    }.catch{ e->
        when(e){
            ...
            is Exception -> {
                ...
                errorHandler.handleError(e.message ?: "Unknown Error")
            }
        }
    }

    protected abstract fun executeRealization(@Nullable params: Params?=null): DataState<Return>

}

[DI 包]

  1. 我尝试使用诸如 BaseUseCaseModule.kt 之类的匕首柄来提供或绑定 BaseUseCase class,但是由于它具有类型参数,因此无法绑定也无法提供。

  2. 目前我无法在 BaseUseCase class 中注入 errorHandler,所以只写了 ErrorHandler 'object' 并静态使用它。 (例如 Object ErrorHandler {})

问题

  1. 如何在抽象中进行字段注入class?
  2. 或者我错过了什么?

How to do field injection inside an abstract class?

目前不支持。

您可以考虑用这两种方法重构您的代码。

第一种方法

将 exception/error 处理链向 UI 移动,这将包括 ViewModel 的方法。

有了这个,您可以构造函数注入您的错误处理程序,然后执行您的用例并将处理程序包装在它周围。

让我们看看可能的解决方案,在草图中,我们将使用干净的架构方法;

ViewModel.kt

@HiltViewModel
class YourViewModel @Inject constructor(private val errorHandler: ErrorHandler, private val useCase : SpecificUseCase) : ViewModel(){

suspend fun realizationFunction(params : Params?=null) : Flow<DataState<Return>> = flow {
    emit(Datastate.Loading)
    try{
       emit(useCase(params))
    }catch(exception : Exception){
       errorHandler.handleError(e.message ?: "Unknown Error")
    }

}
}

在您的特定用例中,我建议您使用存储库模式来执行您的功能以分离关注点,而不是在用例内部执行您的功能。

第二种方法

此方法涉及将错误处理程序更深入地放入链中,并将构造函数注入您的存储库实现中的错误处理程序。

这将使您有机会 运行 在 try/catch 中调用特定的 function/service 并在其中处理您的错误。

第二种方法的缺点可能包括返回错误结果的挑战,但合并资源 class 将使其无缝 - 看起来你已经有了,DataState.

class YourRepositoryImpl(private val errorHandler: ErrorHandler) : YourRepositoryInterface {
  override suspend fun doSomething(params : Params?) : Flow<DataState<Return>> {
   //call your function and use the error handler 
}
}

这使您的代码更清晰,错误处理也更好。

Or Am I missing something?

您可能有兴趣阅读有关应用架构和关注点分离的大量内容。