java - 字符串在 Dagger 中被多次绑定
问题描述
我在匕首中注入字符串时遇到问题
这是我的实现
@Singleton
@Component(
modules = [AndroidInjectionModule::class,
ActivityBuilder::class,
ViewModelModule::class,
NetModule::class,
AppModule::class]
)
interface AppComponent : AndroidInjector<DaggerApplication> {
fun inject(theDApplication: TFTScreenApplication)
override fun inject(instance: DaggerApplication)
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
@BindsInstance
@Named(Constants.API_URL_KEY)
fun apiUrl(apiUrl: String): Builder
@BindsInstance
@Named(Constants.SOCKET_URL_KEY)
fun socketUrl(socketUrl: String): Builder
fun build(): AppComponent
}
}
然后在网络模块
@Module
abstract class NetModule {
@Binds
@Named(Constants.API_URL_KEY)
abstract fun provideApiUrl(apiUrl: String): String
@Binds
@Named(Constants.SOCKET_URL_KEY)
abstract fun provideSocketUrl(socketUrl: String): String
@Module
companion object {
@Provides
@Reusable
@JvmStatic
fun providesOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.build()
}
@Provides
@Reusable
@JvmStatic
fun providesGson(): Gson {
val gsonBuilder = GsonBuilder()
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
return gsonBuilder.create()
}
@Provides
@Reusable
@JvmStatic
fun providesRetrofit(
@Named(Constants.API_URL_KEY) apiUrl: String, gson: Gson
): Retrofit {
return Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl(apiUrl)
.build()
}
@Provides
@Reusable
@JvmStatic
fun providesBackOffStrategy(): BackoffStrategy {
return ExponentialWithJitterBackoffStrategy(5000, 5000)
}
@Provides
@Reusable
@JvmStatic
fun providesLifeCycle(application: Application): Lifecycle {
return AndroidLifecycle.ofApplicationForeground(application)
}
@Provides
@Reusable
@JvmStatic
fun providesScarlet(
@Named(Constants.SOCKET_URL_KEY) socketUrl: String, okHttpClient: OkHttpClient,
backoffStrategy: BackoffStrategy,
lifecycle: Lifecycle
): Scarlet {
return Scarlet.Builder()
.webSocketFactory(okHttpClient.newWebSocketFactory(socketUrl))
.addMessageAdapterFactory(MoshiMessageAdapter.Factory())
.addStreamAdapterFactory(RxJava2StreamAdapterFactory())
.backoffStrategy(backoffStrategy)
.lifecycle(lifecycle)
.build()
}
@Provides
@Reusable
@JvmStatic
fun providesCoinSocket(scarlet: Scarlet): SocketService {
return scarlet.create(SocketService::class.java)
}
@Provides
@Reusable
@JvmStatic
fun providesPISAPIs(retrofit: Retrofit): PISAPIs {
return retrofit.create(PISAPIs::class.java)
}
}
错误是
错误:[Dagger/DuplicateBindings] java.lang.String 被多次绑定:公共抽象接口 AppComponent 扩展 dagger.android.AndroidInjector { ^ @org.jetbrains.annotations.NotNull @Named("API_URL") @BindsInstance com.example。 tftscreen.common.di.component.AppComponent.Builder com.example.tftscreen.common.di.component.AppComponent.Builder.apiUrl(String) @org.jetbrains.annotations.NotNull @Named("SOCKET_URL") @BindsInstance com. example.tftscreen.common.di.component.AppComponent.Builder com.example.tftscreen.common.di.component.AppComponent.Builder.socketUrl(String) java.lang.String 在 com.example.tftscreen.common.di 注入.module.NetModule.provideSocketUrl(socketUrl) @javax.inject.Named("SOCKET_URL") java.lang。字符串在 com.example.tftscreen.common.di.module.NetModule.providesScarlet(socketUrl, ...) 处注入 com.tinder.scarlet.Scarlet 在 com.example.tftscreen.common.di.module.NetModule.providesCoinSocket( Scarlet) com.example.tftscreen.pis.SocketService 在 com.example.tftscreen.pis.data.PISRemoteRepository(socketService, ...) 处注入 com.example.tftscreen.pis.data.PISRemoteRepository 在 com.example.tftscreen 处注入。 pis.PISViewModel(pisRemoteRepository) com.example.tftscreen.pis.PISViewModel 在 com.example.tftscreen.common.di.module.ViewModelModule.bindPISViewModel(pisViewModel) 注入 java.util.Map,javax.inject.Provider> 注入在 com.example.tftscreen.common.presentationLayer。ViewModelFactory(creators) com.example.tftscreen.common.presentationLayer.ViewModelFactory 在 com.example.tftscreen.common.di.module.ViewModelModule.provideViewModelFactory(viewModelFactory) 注入 androidx.lifecycle.ViewModelProvider.Factory 在 com.example 注入。 tftscreen.pis.PISActivity.viewModelFactory com.example.tftscreen.pis.PISActivity 在 dagger.android.AndroidInjector.inject(T) [com.example.tftscreen.common.di.component.AppComponent → com.example.tftscreen. common.di.module.ActivityBuilder_BindMainActivity.PISActivitySubcomponent] 也要求在:com.example.tftscreen.common.di.module.NetModule.provideApiUrl(apiUrl)module.ViewModelModule.provideViewModelFactory(viewModelFactory) androidx.lifecycle.ViewModelProvider.Factory 在 com.example.tftscreen.pis.PISActivity.viewModelFactory 注入 com.example.tftscreen.pis.PISActivity 在 dagger.android.AndroidInjector.inject(T ) [com.example.tftscreen.common.di.component.AppComponent → com.example.tftscreen.common.di.module.ActivityBuilder_BindMainActivity.PISActivitySubcomponent] 也要求在:com.example.tftscreen.common.di.module。 NetModule.provideApiUrl(apiUrl)module.ViewModelModule.provideViewModelFactory(viewModelFactory) androidx.lifecycle.ViewModelProvider.Factory 在 com.example.tftscreen.pis.PISActivity.viewModelFactory 注入 com.example.tftscreen.pis.PISActivity 在 dagger.android.AndroidInjector.inject(T ) [com.example.tftscreen.common.di.component.AppComponent → com.example.tftscreen.common.di.module.ActivityBuilder_BindMainActivity.PISActivitySubcomponent] 也要求在:com.example.tftscreen.common.di.module。 NetModule.provideApiUrl(apiUrl)android.AndroidInjector.inject(T) [com.example.tftscreen.common.di.component.AppComponent → com.example.tftscreen.common.di.module.ActivityBuilder_BindMainActivity.PISActivitySubcomponent] 也在:com.example.tftscreen .common.di.module.NetModule.provideApiUrl(apiUrl)android.AndroidInjector.inject(T) [com.example.tftscreen.common.di.component.AppComponent → com.example.tftscreen.common.di.module.ActivityBuilder_BindMainActivity.PISActivitySubcomponent] 也在:com.example.tftscreen .common.di.module.NetModule.provideApiUrl(apiUrl)
解决方案
@BindsInstance
, 当您需要在运行时将依赖项引入对象图中时,这是最有用的。
@Binds
当您需要将接口绑定到实现并且dagger可以为您构造具体实现时使用(通过@Inject
构造函数)
它看起来不像您的Constants.SOCKET_URL_KEY
&Constants.API_URL_KEY
符合这两个标准中的任何一个,所以...
如果这些确实在编译时可用并且您希望 dagger 提供这些,那么最简单的方法是将以下内容添加到您的模块中:
@Provides
@JvmStatic
@Named(Constants.API_URL_KEY)
fun providesApiUrlKey(): String {
return "YOUR_API_KEY"
}
并删除:
@BindsInstance
@Named(Constants.API_URL_KEY)
fun apiUrl(apiUrl: String): Builder
在任何一种情况下(在运行时或编译时可用),您都需要删除它:
@Binds
@Named(Constants.API_URL_KEY)
abstract fun provideApiUrl(apiUrl: String): String
@Binds
@Named(Constants.SOCKET_URL_KEY)
abstract fun provideSocketUrl(socketUrl: String): String
推荐阅读
- java - 有没有办法更新pitclipse插件中使用的pitest版本?
- php - 我想从调用 Azure API 的“实体”获取域详细信息
- javascript - 无法在静态函数 ReactJs 中调用函数
- c# - 如何使用 for 循环编写 XML 文件以追加元素
- c++ - 在 openssl 中实施 ECIES 1363a-2004
- symfony - Symfony 3 缓存建立与 ezplatform
- c - union integer 成员返回 union 中的数据,而 float 则显示异常
- pandas - 查找熊猫中每个组中的值
- r - 在 R 中使用 voronoi 细分匹配点到节点
- tensorflow - TensorFlow 对象检测 API 微调检查点