Dagger 2 - 从多个独立范围的组件注入单个对象

时间:2016-06-15 08:44:46

标签: dagger dagger-2

我面临的问题是我希望有两个独立的范围,这些范围并不真正属于父子层次结构。就我而言,我想要两种类型的范围:

1)基于“特征”的范围。例如,当用户输入特征时,创建范围组件。当用户离开该功能时,该范围将被销毁。

2)基于“活动”的范围(这适用于Android应用,如果您不使用Android,则对术语感到抱歉)。创建活动时,将创建范围组件。当活动被销毁时,该范围将被销毁。

子组件和组件依赖关系适用于我所追求的目标。这是因为该功能可能在活动被销毁之前结束。同样,活动可能在功能完成之前结束。

我知道我可以使用提供方法而不是成员注入方法并拥有两个独立的组件,但我希望能够简单地将inject中的所有依赖项放在一个对象中。有没有人对此有任何想法?

1 个答案:

答案 0 :(得分:1)

这是我能想到的最佳解决方案。关于将与Activity相关的对象耦合到我的应用程序中的其他状态并实现类似这样的事情,我也有同感。

假设您有三个范围:应用程序范围,活动范围和一些功能范围(例如,具有其配置文件信息等的用户登录状态)。活动和功能范围是应用程序范围的子项,但功能和活动是不相关的兄弟。

不要直接将特色范围对象直接注入活动。而是将一个包含getter的桥接器注入功能范围。

示例:

public interface UserManager {
    @Nullable
    User getLoggedInUser();

    @Nullable
    ShoppingCart getShoppingCart();
}

这些方法可以为空,因为当其他对象尝试访问它们时,用户可能会登录也可能不会登录。如果它们为null,则表示用户未登录;该功能未激活。

这个实现可以从Feature scoped端自由执行依赖注入,因为它没有引用Activity Scope中的任何内容。

public class UserManagerImpl implements UserManager {
   @Inject
   ShoppingCart cart;

   @Inject
   User user;

    public UserManagerImpl(MyApplication application){
        UserScopeComponent component = application.getUserComponent();
        if(component != null) {
            //only attempt injection if the component exists (user is logged in)
            component.inject(this);
        }
    }

    //put simple getters here. They will return null objects if the component didnt inject anything.
}

ApplicationModule提供此对象。它不是应用程序范围或单例;如果登录状态已更改,则每次注入时都要再次初始化它。

@Provides
//No Scope
UserManager provideUserManager(){
    return new UserManagerImpl(context);
}

从那时起,您可以从应用程序的任何位置注入UserManager,调用其getter,检查输出是否为空,然后离开。您的功能状态不再与活动状态相关联,您可以免费使用。