I've a problem in injecting Strings in dagger
This is my implementation
@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
}
}
Then in Net Module
@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)
}
}
The error is
error: [Dagger/DuplicateBindings] java.lang.String is bound multiple times: public abstract interface AppComponent extends 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 is injected at com.example.tftscreen.common.di.module.NetModule.provideSocketUrl(socketUrl) @javax.inject.Named("SOCKET_URL") java.lang.String is injected at com.example.tftscreen.common.di.module.NetModule.providesScarlet(socketUrl, …) com.tinder.scarlet.Scarlet is injected at com.example.tftscreen.common.di.module.NetModule.providesCoinSocket(scarlet) com.example.tftscreen.pis.SocketService is injected at com.example.tftscreen.pis.data.PISRemoteRepository(socketService, …) com.example.tftscreen.pis.data.PISRemoteRepository is injected at com.example.tftscreen.pis.PISViewModel(pisRemoteRepository) com.example.tftscreen.pis.PISViewModel is injected at com.example.tftscreen.common.di.module.ViewModelModule.bindPISViewModel(pisViewModel) java.util.Map,javax.inject.Provider> is injected at com.example.tftscreen.common.presentationLayer.ViewModelFactory(creators) com.example.tftscreen.common.presentationLayer.ViewModelFactory is injected at com.example.tftscreen.common.di.module.ViewModelModule.provideViewModelFactory(viewModelFactory) androidx.lifecycle.ViewModelProvider.Factory is injected at com.example.tftscreen.pis.PISActivity.viewModelFactory com.example.tftscreen.pis.PISActivity is injected at dagger.android.AndroidInjector.inject(T) [com.example.tftscreen.common.di.component.AppComponent → com.example.tftscreen.common.di.module.ActivityBuilder_BindMainActivity.PISActivitySubcomponent] It is also requested at: com.example.tftscreen.common.di.module.NetModule.provideApiUrl(apiUrl)
@Binds? - coroutineDispatcher@Providefor those? I'm a little not clear on how you use the@Bindsannotation . It usualy is used on providing interfaces where classes implement them. - coroutineDispatcher