如何将存储库注入 android 架构组件中的拦截器?
How to inject repository to the interceptor in android architecture components?
我想编写身份验证拦截器,它是从本地数据库加载访问令牌并添加到 android architecture components boilerplate project.
中的请求 header
AuthenticationInterceptor class:
class AuthenticationInterceptor: Interceptor, Authenticator {
/*...*/
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
if (!request.url().encodedPath().equals("/login", ignoreCase = true)) {
tokenRepository.getAccessToken().let {
request = request?.newBuilder()
?.addHeader("Authentication", "Bearer " + it)
?.build()
}
}
return chain.proceed(request)
}
override fun authenticate(route: Route, response: Response): Request? {
/*...*/
}
}
AppModule class 其中将拦截器添加到 OkHttpClient:
@Module(includes = [ViewModelModule::class])
class AppModule {
/*...*/
@Singleton
@Provides
fun provideTokenService(): TokenService {
return Retrofit.Builder()
.client(
OkHttpClient.Builder()
.addNetworkInterceptor(AuthenticationInterceptor()).build()
)
.baseUrl("http://localhost:8080")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.build()
.create(TokenService::class.java)
}
/*...*/
}
我尝试将存储库添加到构造函数,但随后必须将存储库注入 AppModule,这导致构建错误
class AuthenticationInterceptor @Inject constructor(val tokenRepository: TokenRepository): Interceptor, Authenticator {
如果我将存储库注入 class 字段,则存储库将为空
@Inject lateinit var tokenRepository: TokenRepository
所以我的问题是如何将存储库注入拦截器?
好的,我解决了我的问题:
- 首先:我在拦截器上使用构造函数注入
其次:我没有手动创建新实例,而是将拦截器添加到提供者参数中:
fun provideTokenService(authInterceptor: AuthenticationInterceptor): TokenService {
第三点:第二点造成循环依赖,因为repository使用了service,所以我在拦截器中不使用repository而是使用dao(或者创建另一个不使用service的repository)
我想编写身份验证拦截器,它是从本地数据库加载访问令牌并添加到 android architecture components boilerplate project.
中的请求 headerAuthenticationInterceptor class:
class AuthenticationInterceptor: Interceptor, Authenticator {
/*...*/
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
if (!request.url().encodedPath().equals("/login", ignoreCase = true)) {
tokenRepository.getAccessToken().let {
request = request?.newBuilder()
?.addHeader("Authentication", "Bearer " + it)
?.build()
}
}
return chain.proceed(request)
}
override fun authenticate(route: Route, response: Response): Request? {
/*...*/
}
}
AppModule class 其中将拦截器添加到 OkHttpClient:
@Module(includes = [ViewModelModule::class])
class AppModule {
/*...*/
@Singleton
@Provides
fun provideTokenService(): TokenService {
return Retrofit.Builder()
.client(
OkHttpClient.Builder()
.addNetworkInterceptor(AuthenticationInterceptor()).build()
)
.baseUrl("http://localhost:8080")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(LiveDataCallAdapterFactory())
.build()
.create(TokenService::class.java)
}
/*...*/
}
我尝试将存储库添加到构造函数,但随后必须将存储库注入 AppModule,这导致构建错误
class AuthenticationInterceptor @Inject constructor(val tokenRepository: TokenRepository): Interceptor, Authenticator {
如果我将存储库注入 class 字段,则存储库将为空
@Inject lateinit var tokenRepository: TokenRepository
所以我的问题是如何将存储库注入拦截器?
好的,我解决了我的问题:
- 首先:我在拦截器上使用构造函数注入
其次:我没有手动创建新实例,而是将拦截器添加到提供者参数中:
fun provideTokenService(authInterceptor: AuthenticationInterceptor): TokenService {
第三点:第二点造成循环依赖,因为repository使用了service,所以我在拦截器中不使用repository而是使用dao(或者创建另一个不使用service的repository)