android - Dagger 2 定制化提供改造

标签 android dependency-injection kotlin retrofit2 dagger-2

我正在寻找一种更好的方法来管理我的 retrofit DI。我的应用程序可能需要多种改造变体:不可重试、更长的超时、缓存或非缓存等。

我已经知道我可以使用命名参数并在我使用它时指定要提供的不同类型的 okhttp/retrofit,但这意味着我必须为每个可能的组合提供不同的函数,并维护字符串对于命名参数。我可以看到我的 NetworkModule 类变得非常大。

NetworkModule.kt

@Module
class NetworkModule {

    @Provides
    @Singleton
    fun provideHttpLoggingInterceptor(): HttpLoggingInterceptor {
        val loggingInterceptor = HttpLoggingInterceptor { message -> Timber.d(message) }
        loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        return loggingInterceptor
    }

    @Provides
    @Named("standard")
    @Singleton
    fun provideOkHttpClient(httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient {
        val httpClientBuilder = OkHttpClient.Builder()
        if (BuildConfig.DEBUG) httpClientBuilder.addInterceptor(httpLoggingInterceptor)
        return httpClientBuilder.build()
    }

    @Provides
    @Named("standard")
    @Singleton
    fun provideRetrofit(@Named("baseUrl") baseUrl: String, @Named("standard") okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
    }
}

LoginApiModule.kt

@Module(includes = arrayOf(NetworkModule::class))
class LoginApiModule {

    @Provides
    @Singleton
    internal fun provideLoginApi( @Named("standard") retrofit: Retrofit): LoginService {
        return retrofit.create(LoginService::class.java)
    }
}

在这个例子中,我需要一个 provide<some specialization>OkHttpClient()每个专业的功能:

  • 一个用于更长的超时
  • 一个不可重试
  • 两者一个
  • 一个用于缓存
  • 一个用于超时时间较长的缓存
  • 一个用于不可重试等的机器

最佳答案

您可以使用多个 OkHttpClient 实例(共享内容,请参阅:https://github.com/square/okhttp/wiki/Recipes#per-call-configuration)和带有自定义 header 的网络拦截器。人们过去常常这样做是为了缓存(参见:https://krtkush.github.io/2016/06/02/caching-using-okhttp-part-2.html)。另外,不要使用 @Named,请尝试 @Qualifiers !

关于android - Dagger 2 定制化提供改造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47164232/

相关文章:

java - 具有自定义值的 DatePickerDialog

C#依赖注入(inject)问题

kotlin - Kotlin 协程流程中的 RxJava .toList() 等价物

android - 错误:Android Gradle插件仅支持Kotlin Gradle插件1.3.10及更高版本

java - 了解Java的注入(inject)框架HK2吗?

java - Debug模式在带有 Kotlin 的 IDEA 中停止工作

android - ViewPager setCurrentItem(pageId, true) 不平滑滚动

java - 指定的 child 已经有一个 parent 。您必须首先在 child 的 parent 上调用 removeView() (Android)

android - 如何使用 AnimatedImageDrawable 显示以 ByteBuffer 作为源的动画 GIF

scala - 没有类的 Scala 依赖注入(inject)