Dan*_*son 10 android dependency-injection kotlin dagger-2
我正在努力学习匕首和kotlin和mvvm,如果这个问题很奇怪,请原谅我.
如果我有一个NetworkModule,它基本上为应用程序提供了改进,我认为传递我们想要构建改造的基本URL是个好主意.我可以通过App的组件构建函数传递它,以旧的方式,但无法通过@ Component.Builder方法弄清楚如何做到这一点.尝试:
App.kt
DaggerAppComponent.builder()
.application(this)
.networkModule(BuildConfig.BASE_URL)
.build()
.inject(this)
Run Code Online (Sandbox Code Playgroud)
AppComponent.kt
@Singleton
@Component(modules = arrayOf(
AppModule::class,
NetworkModule::class,
AndroidInjectionModule::class,
ActivityBuilder::class))
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
@BindsInstance
fun networkModule(baseUrl: String): Builder
fun build(): AppComponent
}
fun inject(app: App)
}
Run Code Online (Sandbox Code Playgroud)
NetworkModule.kt
@Module
class NetworkModule(baseUrl: String) {
//Attempt to force a public setter for Dagger
var baseUrl: String = baseUrl
set
@Provides
@Singleton
fun provideHttpLoggingInterceptor(): HttpLoggingInterceptor {
val loggingInterceptor = HttpLoggingInterceptor { message -> Timber.d(message) }
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return loggingInterceptor
}
@Provides
@Singleton
fun provideOkHttpClient(httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient {
val httpClientBuilder = OkHttpClient.Builder()
if (BuildConfig.DEBUG) httpClientBuilder.addInterceptor(httpLoggingInterceptor)
return httpClientBuilder.build()
}
@Provides
@Singleton
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
}
Run Code Online (Sandbox Code Playgroud)
错误很明显,但我仍然不明白这是什么意思:)
@Component.Builder is missing setters for required modules or components: [core.sdk.di.module.NetworkModule]
.我试图强制模块为基本URL创建一个公共setter(虽然我认为不需要).
Dav*_*jak 27
要创建组件,需要提供所有模块.现在,Dagger可以创建任何具有无参数构造函数的模块,因此您无需将其传入.
@Module
class NetworkModule(baseUrl: String) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
你声明一个模块在它的构造函数中有一个参数,因此Dagger无法构造它.这是错误试图告诉你的:
@ Component.Builder缺少所需模块或组件的setter:[core.sdk.di.module.NetworkModule]
你有一个必须手动添加的模块(因为Dagger无法构造它),但你@Component.Builder
没有办法包含它.
您提供的是String
作为基本URL 的绑定,这不是最好的主意,因为您可能希望String
在项目中使用多个对象.您应该考虑使用a @Qualifier
,但稍后会更多.
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
// binds a `String` to the component
@BindsInstance
fun networkModule(baseUrl: String): Builder
// no method to set the NetworkModule!
fun build(): AppComponent
}
Run Code Online (Sandbox Code Playgroud)
要解决您的问题,您有2个选项.您可以创建一个setter并自己将url传递给模块构造函数,然后在组件(1)上设置模块,也可以绑定url并在模块中使用它,从构造函数中删除参数(2).
这是一种更简单的方法,因为您只需自己创建模块并将其传递给Dagger组件构建器.您所要做的就是将String的绑定替换为模块的setter.
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
// add the module manually
fun networkModule(networkModule: NetworkModule): Builder
fun build(): AppComponent
}
Run Code Online (Sandbox Code Playgroud)
创建组件时,您现在必须将模块添加到构建器.
builder
.application(app)
.networkModule(NetworkModule(MY_BASE_URL)) // create the module yourself
.build()
Run Code Online (Sandbox Code Playgroud)
要将url绑定到组件并在模块中使用它 - 就像你想要的那样 - 你必须从构造函数中删除参数.
@Module
class NetworkModule() { /* ... */ } // no-arg constructor
Run Code Online (Sandbox Code Playgroud)
通过这样做,Dagger现在可以创建模块,您将摆脱该错误.把网址在构造函数,而不是我们想要得到它通过在被匕首,但使用上面提到String
是不是最佳的,因为它的字面告诉匕首,有你想要的是任何价值String
.您应该使用限定符来添加适当的区别,例如@Named("baseUrl") String
.
有关限定符的更多信息
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
// bind a `String` named "baseUrl" to this component
@BindsInstance
fun baseUrl(@Named("baseUrl") baseUrl: String): Builder
fun build(): AppComponent
}
Run Code Online (Sandbox Code Playgroud)
Dagger现在知道@Named("baseUrl") String
我们现在也可以在我们的模块中使用.
@Module
class NetworkModule() {
// other methods omitted
@Provides
@Singleton
fun provideRetrofit(
// request a String named baseUrl from Dagger
@Named("baseUrl") baseUrl: String,
okHttpClient: OkHttpClient
): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
// ...
.build()
}
Run Code Online (Sandbox Code Playgroud)
就是这样.
归档时间: |
|
查看次数: |
2703 次 |
最近记录: |