Строка связана несколько раз в Dagger - PullRequest
0 голосов
/ 10 июня 2019

У меня проблема с вводом строк в кинжал

Это моя реализация

@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.String вводится в com.example.tftscreen.common.di.module.NetModule.providesScarlet (socketUrl, ...) com.tinder.scarlet.Scarlet вводится в com.example.tftscreen.common.di.module.NetModule.providesCoinSocket (алый) 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 (создатели) 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)

1 Ответ

0 голосов
/ 28 июня 2019

@BindsInstance, наиболее полезно, когда у вас есть зависимости, которые необходимо ввести в граф объектов в время выполнения .

@Binds используется, когда вам нужно привязать интерфейс к реализации. и кинжал может создать конкретную реализацию для вас (через конструктор @Inject)

Не похоже, что ваши Constants.SOCKET_URL_KEY & Constants.API_URL_KEY соответствуют ни одному из этих критериев, поэтому ...

Если это правда, что они доступны во время компиляции и , то вам нужен кинжалчтобы обеспечить это, проще всего сделать это, добавив в свой модуль следующее:

@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
...