如何将存储库注入 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)