java - Dagger 2 : Multiple entries with same key

标签 java dependency-injection kotlin dagger-2

简短说明

通过组件架构描述的简化UML图。

enter image description here

有一个异常(exception):

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。它适用于我的情况,但这听起来像是一个肮脏的解决方案。

有一些代码。

应用程序组件:

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

应用演示组件

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

游戏 session 组件

@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 user guide讨论两种类型的绑定(bind):

Published bindings are those that provide functionality that is used by other parts of the application.

Internal bindings are the rest: bindings that are used in the implementation of some published type and that are not meant to be used except as part of it. These bindings are usually for package-private types or are qualified with package- private qualifiers.

当您设计模块和组件时,您可能需要考虑这一点。您目前拥有的:

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

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

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

这同样适用于您的模块。与组件一样,模块既可以发布绑定(bind)也可以内部化绑定(bind)。为什么不在 ApplicationComponent 级别将 GSON 绑定(bind)到另一个模块中并将其发布到依赖组件呢?然后您可以摆脱 GameSessionModule 内的 GSON 绑定(bind),这似乎是导致问题的原因。

关于java - Dagger 2 : Multiple entries with same key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40693666/

相关文章:

java - 使用 OpenJDK 将 Jenkins 节点/代理作为 Windows 服务运行

c# - asp.net 5 自定义类中的依赖注入(inject),正确的方法是什么?

maven - 像kotlin-gradle-plugin一样,如何将kotlin-js-library更新到1.1.3?

java - 如何为JUNIT开源做贡献

java - 将公共(public) Maven 存储库用于库而不是本地的优点

java - 从注入(inject)的实例 CDI 获取准确的对象

dependency-injection - 与 MonoTouch 兼容的 IoC 库?

java - Spring 和 AOP - 处理每个抛出的异常

kotlin - Kotlin flatMapTo无法编译

java - Java 中的 SQL 命令错误