【发布时间】: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