Intereting Posts
Элементы списка RecycleView не отображаются Kotlin: получить ссылку на функцию экземпляра класса Kotlin 'небезопасный вызов ошибки компиляции с помощью NULL-приемника после нулевой проверки Проекция звезды Котлина на контравариантные типы Присвоение свойств объекту javascript с использованием динамических имен свойств Поддержка Base64 для разных уровней API Как прикрепить элемент HTML или DocumentFragment к DOM? Есть ли способ связать свойство appConfig с tornadofx? Извлечь текстовое значение из объекта, чтобы установить текст в listView Котлин: когда и как следует использовать выражения лямбда Kotlin – Возможно ли инициализировать объект-компаньон перед блоком init в классе? Тема Kotlin Quasar и проблема блокировки канала Каковы преимущества языка программирования Kotlin? Kotlin – Как сделать делегат недвижимости по карте с пользовательским именем? SearchView всегда расширялся, на панели инструментов?

Кинжал 2: несколько записей с одним и тем же ключом

Краткое объяснение

Упрощенная диаграмма UML, которая описывается архитектурой Components .

введите описание изображения здесь

И есть исключение:

 java.lang.IllegalArgumentException: Multiple entries with same key: gson=com.example.di.AppPresentationComponent and gson=com.example.di.gamesession.GameSessionComponent 

Dagger 2 не может решить, из какого Component предоставить экземпляр Gson .

Я никогда не работаю с множественным наследованием. Что вы можете порекомендовать для решения моей ситуации?

Я могу избавиться от GameSessionComponent и переместить gameSessionManager() в GameSessionPresentationComponent . Это будет работать в моем случае, но это звучит как грязное решение.

Существует некоторый код.

AppComponent:

 @PerApplication @Component(modules = arrayOf( AppModule::class, TextsModule::class, AudioModule::class, FontsModule::class, TexturesModule::class, QuestModule::class, GameSaveModule::class )) interface AppComponent { fun componentsHolder(): ComponentsHolder fun gdxContext(): GdxContext fun rxHelper(): RxHelper fun textsManager(): TextsManager fun soundsManager(): AudioManager fun fontsManager(): FontsManager fun texturesManager(): ThemesManager fun questManager(): QuestManager fun gameSaveManager(): GameSaveManager } 

AppPresentationComponent

 @PerApplicationPresentation @Component( dependencies = arrayOf(AppComponent::class), modules = arrayOf(AppPresentationModule::class) ) interface AppPresentationComponent : AppComponent { fun fonts(): Fonts fun audio(): Audio fun texts(): Texts fun textures(): Textures fun router(): KRQRouter fun launch(): LaunchScreen fun mainMenu(): MenuScreen fun settingsDialog(): SettingsDialog fun questInfoDialog(): InfoDialog } 

GameSessionComponent

 @PerGameSession() @Component( dependencies = arrayOf(AppComponent::class), modules = arrayOf(GameSessionModule::class) ) interface GameSessionComponent : AppComponent { fun storyTeller(): StoryTeller } 

GameSessionPresentationComponent

 @PerGameSessionPresentation @Component( dependencies = arrayOf(AppPresentationComponent::class), modules = arrayOf(GameSessionPresentationModule::class, GameSessionModule::class) ) interface GameSessionPresentationComponent : AppPresentationComponent { fun storyTeller(): StoryTeller fun story(): StoryScreen fun gameoverDialog(): GameoverDialog fun inGameMenu(): InGameMenu fun donateDialog(): DonateDialog } 

В руководстве пользователя Dagger рассказывается о двух типах привязок:

Опубликованные привязки – это те, которые предоставляют функциональные возможности, которые используются другими частями приложения.

Внутренние привязки – это остальное: привязки, которые используются при реализации некоторого опубликованного типа и которые не предназначены для использования, кроме как часть его. Эти привязки обычно относятся к типам пакетов-частных или имеют квалификацию с частными сертификатами пакетов.

Вероятно, вам стоит подумать об этом, когда вы разрабатываете свои модули и компоненты. Что у вас сейчас есть:

 interface AppPresentationComponent : AppComponent interface GameSessionComponent : AppComponent interface GameSessionPresentationComponent : AppPresentationComponent 

это иерархия, в которой каждый компонент публикует все привязки к зависимым компонентам. Это довольно сложно, потому что ваша иерархия интерфейсов не соответствует иерархии компонентов для зависимых компонентов. Настройтесь таким образом, легко получить дубликат привязки. В идеале вы не должны доходить до ситуации, когда вам нужно рассуждать о множественном наследовании для компонентов.

На этом этапе я предлагаю вам реорганизовать интерфейсы компонентов, чтобы они не наследовали друг от друга, и вы сможете узнать, какие привязки должны быть опубликованы для зависимых компонентов и которые могут (и должны) быть интернализованы.

То же самое касается ваших модулей. Как компонент, модуль может публиковать и интернализировать привязку. Почему бы не связать GSON в другом модуле на уровне ApplicationComponent и опубликовать его в зависимых компонентах? Затем вы можете избавиться от привязки к GSON внутри GameSessionModule который, похоже, вызывает проблему.