【问题标题】:Dagger2 Component depends on more than one scoped componentDagger2 组件依赖于多个作用域组件
【发布时间】:2017-08-07 10:50:47
【问题描述】:

嘿,我有三个组件:

  • 应用程序 -> 提供上下文(例如 LocationUsecase)

  • ApiService -> 提供改造(休息调用)

  • DBService -> 提供 RoomDB(保存在 SQLite 中)

有时我想在我的 ViewModel 中使用多个组件 - 但我遇到了异常,我可能不会 .inject(ViewModel) 对许多组件使用同一个类。

UserViewModel{
   @Inject ApiService api;
   @Inject DatabaseService db;

   public User(){
     Application.getApiComponent.inject(this)
     Application.getDBComponent.inject(this)
  }

}

因为我想解耦组件(用于测试目的) 我决定将依赖项添加到我的 ApplicationComponent 中,并在注入 Application 时能够使用 albo DB 和 REST

@PerApplication
@Component(dependencies = {DBComponent.class, RestApiComponent.class},
        modules = {ApplicationModule.class})
public interface ApplicationComponent{...}

@DbScope
@Component(modules = {DBModule.class})
public interface DBComponent {...}

@RestScope
@Component(modules = {RestApiRetrofitModule.class})
public interface RestApiComponent {...}

这次我遇到了编译错误:

PerApplication ApplicationComponent 依赖于多个作用域组件: @DbScope 数据库组件 @RestScope RestApiComponent

问题是当人们使用多个依赖项时,我没有找到任何示例 - 它是否受到限制? 当我删除 DBComponent 的 @Scope 时,这很好 - 但我有无范围的实例,每次新实例都会返回 当我从依赖项中删除一个组件时,我也将毫无错误地构建。

如何在我的组件中使用两个依赖项?

【问题讨论】:

    标签: android dagger-2


    【解决方案1】:

    你快到了 - dependencies = 需要进入依赖(子)组件

    @PerApplication
    @Component(modules = ApplicationModule.class)
    public interface ApplicationComponent{...}
    
    @DbScope
    @Component(dependencies = ApplicationComponent.class, modules = DBModule.class)
    public interface DBComponent {...}
    
    @RestScope
    @Component(dependencies = ApplicationComponent.class, modules = RestApiRetrofitModule.class)
    public interface RestApiComponent {...}
    

    现在只需确保您公开了绑定在 ApplicationComponent 的模块集中的依赖项,以便依赖组件可以使用它们。

    因此,如果您在ApplicationComponent 级别绑定SharedPreferences,并且您希望与依赖组件共享该依赖项,则需要在ApplicationComponent 中编写提供方法

    @Component
    public interface ApplicationComponent { 
    
        SharedPreferences exposeSharedPreferences();  
    }
    

    此外,您可能需要重新考虑为 DB 和 REST 创建范围 - 这些更像是功能分组,您希望的解耦可以通过模块来完成。

    在 Android 应用中,您通常只需要几个范围 - @PerApp@PerActivity 范围,因为范围跟踪生命周期,这是两个主要的生命周期。

    【讨论】:

    • 感谢您的回答。在您的示例中 DBScope 成为 PerApplication 的父范围?并且在初始化 Dagger_DBComponent.builder 时,我会从子级(ApplicationComponent)获得范围吗?这是一个很好的方法,我会尽快尝试,但问题仍然存在:“是否可以使用多个依赖项?”
    • @murt 直接回答您的问题,不可能有一个组件依赖于多个作用域组件。请参阅this answer 了解原因
    • 另外,在示例中@PerApplication 是根范围。 @DbScope@RestScope 将是更窄的范围
    • @DavidRawson 这有点奇怪,因为通常您希望将基本模块(例如 net、repo、ops)与了解应用程序级模块的每个依赖项隔离开来。实际上,我坚持这个问题,'因为在我的项目中,我有大约十几个组件(每个项目模块一个),它们形成一棵树,其中根是应用程序组件,但现在是在基础中拥有单例依赖项的唯一方法components 是将它们实现为真正的单例。
    • “[如果]您希望与依赖组件共享该依赖项,则需要编写配置方法...” - 这是我在处理组件依赖项时缺少的关键。谢谢你 x1000!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    相关资源
    最近更新 更多