匕首2:具有相同键的多个条目
简短的解释
由Components
体系结构描述的简化的UML图。
还有一个例外:
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
是每个组件将其所有绑定发布到相关组件的层次结构。 这是相当混乱的,尤其是因为您的接口层次结构不遵循组件到依赖组件的层次结构。 像这样设置,很容易获得重复的绑定。 理想情况下,你不应该达到你必须推理组件的多重继承的情况。
在这个阶段,我会建议你重构你的组件接口,使它们不会相互继承,你将能够发现哪些绑定需要发布到依赖组件,哪些可以(也应该)被内化。
这同样适用于你的模块。 就像一个组件一样,一个模块可以发布和内部化一个绑定。 为什么不在ApplicationComponent
级别的另一个模块中绑定GSON并将其发布到相关组件? 然后你可以摆脱GameSessionModule里面的GameSessionModule
绑定,这似乎是造成这个问题的原因。