【问题标题】:Dagger 2 customizing provided retrofitDagger 2 定制提供改造
【发布时间】:2017-11-07 17:42:13
【问题描述】:

我正在寻找一种更好的方法来管理我的改造 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() 函数用于每个专业化:

  • 一个更长的超时时间
  • 一个不可重试
  • 两全其美
  • 一个用于缓存
  • 用于缓存的超时时间较长
  • 一个用于具有不可重试性等的缓存器。

【问题讨论】:

  • 所以你想只用一个提供函数来实现这个?
  • 是的,我想是的!也许不可能,我应该只使用不同的模块类?
  • 还在考虑。但是为什么不同的模块类。这些功能将位于单个(网络)模块中,对吧?
  • 很丑,但是你可以有一组@Named提供方法
  • 您还可以拥有一个工厂,根据给定的标准创建您的 http 客户端,并在网络模块中提供工厂。你也可以看看 dagger 的多重绑定功能——这似乎也是一个很好的用例。

标签: android dependency-injection kotlin retrofit2 dagger-2


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多