问题描述
我想尝试尽可能简单地描述这个问题。
我的项目目前正在使用 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 (将#修改为@)