匕首2:具有相同键的多个条目

时间:2016-11-19 13:50:32

标签: java dependency-injection kotlin dagger-2

简短说明

java.lang.IllegalArgumentException: Multiple entries with same key: gson=com.example.di.AppPresentationComponent and gson=com.example.di.gamesession.GameSessionComponent 架构描述的简化UML图。

enter image description here

还有一个例外:

Dagger 2

Component无法决定Gson提供GameSessionComponent个实例。

我从未使用多重继承。您可以推荐什么来解决我的情况?

我可以处置gameSessionManager()并将GameSessionPresentationComponent移至@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 } 。它可以在我的情况下工作,但这听起来像一个肮脏的解决方案。

有一些代码。

AppComponent:

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

AppPresentationComponent

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

GameSessionComponent

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

GameSessionPresentationComponent

{{1}}

1 个答案:

答案 0 :(得分:2)

Dagger user guide讨论了两种类型的绑定:

  

已发布的绑定是提供所使用功能的绑定   通过应用程序的其他部分。

     

内部绑定是其余的:在中使用的绑定   某些已发布类型的实现,并非意图   除了作为其中一部分使用。这些绑定通常用于   package-private类型或使用package-private限定   限定符。

在设计模块和组件时,您可能需要考虑这一点。你现在有什么:

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

是一个层次结构,其中每个组件都将所有绑定发布到依赖组件。这非常令人困惑,特别是因为您的接口层次结构不遵循组件的层次结构到依赖组件。像这样设置,很容易得到重复的绑定。理想情况下,您不应该达到必须推断组件的多重继承的情况。

在这个阶段,我建议您重构组件接口,以便它们不会相互继承,并且您将能够发现哪些需要的绑定要发布到依赖组件哪些可以(并且应该)内化。

这同样适用于您的模块。像组件一样,模块可以发布和内化绑定。为什么不在ApplicationComponent级别的另一个模块中绑定GSON并将其发布到依赖组件?然后你可以摆脱GameSessionModule里面的GSON的绑定,这似乎导致了问题。