Android 上的 Koin 注入 Stackover 流程​​错误不确定如何重构以阻止此问题,寻求帮助

问题描述

我想尝试尽可能简单地描述这个问题。

我的项目目前正在使用 Koin 进行依赖注入。 我试图在可能的情况下坚持使用干净的架构。 我的项目由 UseCases 组成,它将注入一个存储库,其中包含我的 Retrofit apiInterface,在某些情况下还包含一个映射器。

UseCases 在大多数情况下是从 viewmodel 调用的。

一切都很顺利,直到我被要求向 OkHttpClientBuilder 添加一个 Authenticator。

OkHttpClientBuilder 是项目的自定义类,允许对返回构建的 OkHttpClient 的标头等进行操作,但我的构造函数要求注入此身份验证器。

class TokenAuthenticator(private val refreshToken: RefreshTokenUseCase): Authenticator {

override fun authenticate(route: Route?,response: Response): Request? {
    refreshToken()?.let { token ->
        return response.request().newBuilder()
            .header("Authorisation",token)
            .build()
    }
    return null
}

private fun refreshToken(): String? {
    var newToken: String? = null
    runBlocking {
        refreshToken.invoke(this) { result ->
            result.result(
                onSuccess = {
                    newToken = it.access_token
                }
            )
        }
    }
    return newToken
}

}

在这里的主要问题是我已经设法通过注入创建了一个循环。

循环如下:

TokenAuthenticator(RefreshTokenUseCase)    ->
OkHttpClient(TokenAuthenticator)    ->
Retrofit(OkHttpClient)    ->
AuthApi(Retrofit)   ->
AuthRepo(AuthApi)  ->
RefreshTokenUseCase(repo: AuthRepoInterface)    *Beginning*

如您所见,我已经设法创建了一个循环,但我不确定如何改进。

OkHttpClientBuilder 是:

    object OkHttpClientBuilder {

    fun createOkHttp(
        appContext: Context,authenticator: TokenAuthenticator
    ): OkHttpClient {
        val builder = OkHttpClient.Builder()
            .writeTimeout(30,TimeUnit.SECONDS)
            .connectTimeout(30,TimeUnit.SECONDS)
            .readTimeout(30,TimeUnit.SECONDS)
            .authenticator(authenticator)
            .addInterceptor { chain ->
                val original = chain.request()
                val requestBuilder = original.newBuilder()
                    .header("Accept","application/json")
                    .header("Content-Type","application/json")
                    .header("language",Locale.getDefault().language)
                    .method(original.method(),original.body())
                val request = requestBuilder.build()
                chain.proceed(request)
            }

        val collector = getChuckCollector(appContext)
        val interceptor = getInterceptor(appContext,collector)
        builder.addInterceptor(interceptor)

        return builder.build()
    }
}

fun getChuckCollector(context: Context): ChuckerCollector {
    return ChuckerCollector(
        context,showNotification = true,retentionPeriod = RetentionManager.Period.ONE_HOUR
    )
}

fun getInterceptor(context: Context,collector: ChuckerCollector): ChuckerInterceptor {
    return ChuckerInterceptor.Builder(context)
        .collector(collector)
        .maxContentLength(250_000L)
        .redactHeaders("Auth-Token","Bearer")
        .alwaysReadResponseBody(true)
        .build()
}

用例是:

    class RefreshTokenUseCase(
    private val authRepository: AuthRepositoryInterface,private val storageRepository: LocalUserRepositoryInterface
): EmptyParamsUseCase<GetTokenResult>() {
    override suspend fun run(): Result<GetTokenResult,Exception> {
        return try {
            val authenticate = authRepository.refreshToken(storageRepository.getRefreshToken())
            if(authenticate.errorResponse == null) {
                storageRepository.setAuthToken(authenticate.access_token)
                storageRepository.setRefreshToken(authenticate.refreshToken)
                storageRepository.setUserId(authenticate.user_id)
                storageRepository.setExpiresTime(authenticate.expires_in)
            }

            return Result.Success(authenticate)
        } catch (ex: Exception) {
            Result.Failure(ex)
        }
    }
}

基本上,我不确定如何从 OkHttpClient 类访问存储,而不必固有地注入改造 ApiInterface 类,这将需要创建改造,然后再次需要 OkHttpClient,导致循环继续.

请帮忙。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)