[英]Android - cannot inject Interface class into module
我是 Koin 的新手,所以希望有人能够指出我遇到的问题的方向。
我有一个接口 class:
interface UserApi {
@POST("/refreshToken")
@Headers("Accept: application/json")
suspend fun refreshToken(@Body x: X): TokenResponseDto
}
我有一个 class ,我在其中使用UserApi
进行 API 调用。
class TokenAuthenticator(
private val userApi: UserApi
) : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? = synchronized(this) {
runBlocking { userApi.refreshToken() }
}
}
到目前为止一切都很好,但现在我想注入TokenAuthenticator
class。 如果我出于测试目的删除构造函数,我可以看到应用程序正在运行并且一切都很好,但是当我添加 userApi 构造函数变量时——我需要它,我得到并出错。
我的 NetworkModule 看起来像这样:
val networkModule = module {
single<UserApi> {
Retrofit.Builder()
.client(get(named("httpClient")))
.baseUrl(get<String>(named("...")))
.addConverterFactory(
...
)
.build()
.create(UserApi::class.java)
}
single(named("httpClient")) {
val tokenAuthenticator: TokenAuthenticator = get()
OkHttpClient.Builder()
.authenticator(tokenAuthenticator)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
}
single {
TokenAuthenticator(get())
}
}
错误:
at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:53)
更新:有人建议在 TokenAuthenticator 中使用 lambda function。 我认为这个解决方案更简单。
class TokenAuthenticator(
private val userApi : () -> UserApi
) {
// ...
fun authenticate(...) {
userApi().refreshToken()
}
}
在这种情况下,您可以像这样定义您的 koin 定义。
single {
TokenAuthenticator {
get()
}
}
我的回答是:
可能有更好的解决方案,但这是一个匆忙的解决方案。 你可以改进它。
让我们解耦TokenAuthenticator
和UserApi
。 它们稍后将通过TokenRefresher
连接。
interface TokenRefresher {
fun refreshToken()
}
class TokenAuthenticator(
private val tokenRefresher: TokenRefresher
) : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? = synchronized(this) {
runBlocking { tokenRefresher.refreshToken() }
}
}
在 koin 模块中添加一个令牌刷新器。
val networkModule = module {
single<TokenRefresher> {
object : TokenRefresher {
// now use the userApi
override fun refreshToken() {
val userApi: UserApi = get()
userApi.refreshToken()
}
}
}
single<UserApi> {
Retrofit.Builder()
.client(get(named("httpClient")))
.baseUrl(get<String>(named("...")))
.addConverterFactory(
...
)
.build()
.create(UserApi::class.java)
}
single(named("httpClient")) {
val tokenAuthenticator: TokenAuthenticator = get()
OkHttpClient.Builder()
.authenticator(tokenAuthenticator)
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
}
single {
TokenAuthenticator(get())
}
}
希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.