【问题标题】:Dagger 2: Inject child class based on logicDagger 2:基于逻辑注入子类
【发布时间】:2017-09-12 11:55:22
【问题描述】:

在我的 android 中使用 Dagger 2 和 MVP 模式,并在一些概念上有点挣扎。

假设我有一个演示者DashboardPresenter,当我在活动或其他演示者中需要它时,我会使用以下方法注入它:

@inject
DashboardPresenter presenter;

或者在其他presenter的构造函数中:

@inject
public AccountPresenter(DashboardPresenter presenter) {
    //init
}

现在我不太确定它是如何工作的,但我想做以下事情:

假设我创建了一个BaseDashboardPresenter,它将作为父级

我为它创建了 2 个孩子:NormalDashboardPresenterProDashboardPresenter 都从它扩展而来。

当我想在一个活动或另一个演示者中使用它时,我通过调用注入 Base Presenter

@inject
BaseDashboardPresenter presenter;

并且我覆盖了@inject 行为,以基于布尔值注入其中一个孩子。 所以是这样的:

//in BaseDashboardPresenter 
override inject() {
    if(Utility.checkIfUserIsPro()) {
        inject ProDashboardPresenter();
    } else {
        inject NormalDashboardPresenter();
    } 
}

所以从我的活动中我只是调用了 Base 类中的抽象方法,区别只是注入了哪个子类。

这可能吗? 如果需要,很乐意提供更多说明。

【问题讨论】:

    标签: android mvp dagger-2


    【解决方案1】:

    与其他答案相反,我认为您的模块不应包含任何逻辑。这不是人们所期望的。

    另外,如果一个变体需要A,而另一个依赖于B,您的@Provides 方法会如何?现在您需要声明不需要的依赖项,从这里开始变得更加混乱。


    相反,您应该为每个选项创建一个模块,并在组件中包含正确的模块。

    // module providing pro version
    componentBuilder.addPresenterModule(new ProModule());
    
    // or a default one
    componentBuilder.addPresenterModule(new DefaultModule());
    

    这样,无论您在哪里构建组件,您都可以决定其中应该包含什么。一种更专用的方法是使用 2 个完全不同的组件,其中每个组件使用不同的模块等。这对于更复杂的项目可能有意义,但在您的情况下,模块似乎就足够了。

    【讨论】:

    • 感谢您的回答,但为了确保我理解,您的意思是我创建了 2 个不同的模块,在活动初始​​化级别,我进行检查并添加我想要的模块?如果是这样,如果这些模块还具有其他常见的依赖关系,我可以将其作为基本模块,还是必须为每个模块重复它们?所以如果问题看起来很愚蠢,我只是想开始在匕首世界
    • @Youssef 一个组件可以有多个模块,因此您可以将公共依赖项移动到第三个模块中
    【解决方案2】:

    为此,您应该在模块中添加如下内容:

    @Provides
    public BaseDashboardPresenter provideDashboardPresenter(OtherPresenter presenter) {
        if (Utility.checkIfUserIsPro()) {
            return new ProDashboardPresenter();
        } else {
            return new NormalDashboardPresenter(presenter);
        }
    }
    

    【讨论】:

    • @Provides 方法添加逻辑通常不是一个好主意,如果两个变体具有不同的依赖关系,它会变得混乱且难以维护
    • 很抱歉在我的问题中省略了这一点,但是 NormalDashboardPresenter 将其他演示者和类作为参数并且它们都被注入了。 @inject public NormalDashboardPresenter (OtherPresenter) { } 所以我还需要创建 OtherPresenter 的实例?
    • @DavidMedenjak 是的,你是对的。 Dagger 应该只管理注入并且不应该包含逻辑。Youssef,你可以将额外的演示者作为参数传递(我已经编辑了我的答案)
    • @guillaume 谢谢你的例子,我现在就试试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 2022-09-30
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多