Android ViewModel DI 依赖注入错误

问题描述 投票:0回答:1
@HiltViewModel
class LoginViewModel
@Inject constructor(private val authRepository: AuthRepository) : ViewModel() {

    private val _hidePassword = MutableLiveData(false)
    val hidePassword: LiveData<Boolean>
        get() = _hidePassword


    private val _autoLogin = MutableLiveData(false)
    val autoLogin: LiveData<Boolean>
        get() = _autoLogin

    private val _loginError = MutableLiveData(false)

    val loginError: LiveData<Boolean>
        get() = _loginError


    fun login(userId: String, password: String) {
        viewModelScope.launch {
            kotlin.runCatching {
                authRepository.login(
                    LoginReqeustDto(
                        userId = userId,
                        password = password
                    )
                )
            }.onSuccess {
//                val prefs = NewJeansBunniesApplication.prefs
//                prefs.accessToken = it.accessToken
//                prefs.autoLogin = autoLogin.value?:false
//                if(autoLogin.value == true)
//                    prefs.refreshToken = it.refreshToken
//                _loginError.value = false
            }.onFailure { e ->
                _loginError.value = true
                Log.d("LoginViewModel", e.message.toString())
            }
        }
    }

    fun loginError(status: Boolean) {
        _loginError.value = status
    }

    fun autoLogin(status: Boolean) {
        _autoLogin.value = status
    }

    fun hidePassword(status: Boolean) {
        _hidePassword.value = status
    }

}

如果我省略 private val authRepository: AuthRepository,它会正常工作,但是如果我放入 private val authRepository: AuthRepository,它会显示 Cannot create an instance of class newjeans.bunnies.auth.viewmodel.LoginViewModel。

问题可能出在下面的代码中。

interface AuthApi {
    @POST("/api/auth/login")
    suspend fun login(
        @Body loginRequestDto: LoginReqeustDto
    ): LoginResponseDto

    @POST("/api/auth/signup")
    suspend fun signup(
        @Body signupRequestDto: SignupReqeustDto
    ): SignupResponseDto

    @PATCH("/api/auth")
    suspend fun refresh(
        @Header("refresh-token") token: String
    )
}
class ApiRepositoryImpl @Inject constructor(
    private val authApi: AuthApi
) : AuthRepository {
    override suspend fun login(loginRequestDto: LoginReqeustDto): LoginResponseDto {
        return authApi.login(loginRequestDto)
    }

    override suspend fun signup(signupRequestDto: SignupReqeustDto): SignupResponseDto {
        return authApi.signup(signupRequestDto)
    }

    override suspend fun refresh(token: String) {
        return authApi.refresh(token)
    }
}
interface AuthRepository {
    suspend fun login(loginRequestDto: LoginReqeustDto): LoginResponseDto
    suspend fun signup(signupRequestDto: SignupReqeustDto): SignupResponseDto
    suspend fun refresh(token: String)
}
@Module
@InstallIn(SingletonComponent::class)
class RepositoryModel {

    @Provides
    @Singleton
    fun provideAuthRepository(apiRepositoryImpl: ApiRepositoryImpl): AuthRepository =
        apiRepositoryImpl

}
@Provides
@Singleton
fun provideAuthApi(retrofit: Retrofit): AuthApi =
    retrofit.create(AuthApi::class.java)

我检查了版本并尝试使用 hiltViewModel。

android kotlin dependency-injection viewmodel
1个回答
0
投票

如果没有堆栈跟踪,我不太确定,但我发现您提供存储库的方式存在问题。您可以查看this文章或其他类似

所以基本上,要将接口与实现映射,您必须使用@Binds。或者,如果您想使用 @Provides 代替,它会有不同的外观。 @Binds 类似的东西:

@Module
@InstallIn(SingletonComponent::class)
interface RepositoryModel {

    @Binds
    fun provideAuthRepository(apiRepositoryImpl: ApiRepositoryImpl): AuthRepository
}

或者使用@Provides

@Module
@InstallIn(SingletonComponent::class)
class RepositoryModel {

    @Provides
    @Singleton
    fun provideAuthRepository(authApi: AuthApi): AuthRepository =
        ApiRepositoryImpl(authApi)

}
© www.soinside.com 2019 - 2024. All rights reserved.