【问题标题】:Android dagger dependency cycleAndroid dagger 依赖循环
【发布时间】:2018-11-30 04:32:45
【问题描述】:

我有 2 个具有相同 Scope 的依赖项,它们相互需要。

我的依赖项是具有不同方法的域服务(每种方法都有不同的业务案例)。一些业务案例可能会使用其他领域的方法。

为此,我需要 domain1 可用于 domain2,反之亦然。

但是当我这样做时,我得到一个依赖循环编译错误。谷歌搜索了一段时间后,我发现为了克服这个问题,我必须使用 @Inject 注释而不是 @Module 中的构造函数参数注入依赖项之一。

当我尝试这个代码编译但匕首根本没有注入第二个依赖。

有没有办法用 Dagger 实现我想要的?

【问题讨论】:

  • 答案是肯定的,但是没有代码没人能告诉你你做错了什么。
  • 我认为您的依赖结构可能存在根本问题,您可以发布一些代码吗?

标签: android dependency-injection cycle dagger


【解决方案1】:

你的问题: AClass对BClass有构造函数依赖,BClass对AClass有构造函数依赖。即使没有 Dagger,这也行不通:如果它们相互依赖,你会先创建哪个?

您尝试的解决方案:如果您使用 new 创建您的一个类 (BClass),并且它不再具有 @Inject-annotated 构造函数,您可以等到构造 AClass 之后填充您的 BClass 实例。但是,如果您使用new 创建对象,则需要通过将其传递给成员注入方法或MembersInjector<BClass> 对象来注入它。您还需要确保这发生在@Provides 方法之外(因为调用@Provides 的全部原因是您可以构造一个值以传递给AClass 的构造函数)。这是脆弱且相当丑陋的。

我的建议:使用indirection via Provider。让 AClass 注入 Provider<BClass>,或 BClass 注入 Provider<AClass>,或两者兼而有之。只要您不在构造函数中调用get,您将允许 Dagger 创建 AClass 并将 BClass 的创建推迟到您需要它。您无需额外配置即可为您在组件中绑定的任何类 T 注入 Provider<T>Lazy<T>;有关可用注射的完整列表,请参阅 "Bindings in the Graph" in the User's Guide

【讨论】:

  • 感谢您的宝贵时间,这是很好的信息。最后,我决定在表示层和领域层之间添加一个新的额外层(“Interactor”),以将多个领域合并为复杂的业务案例。
  • @Jeff 你能解释一下如何实现这一点
  • @WISHA 如果没有特定代码,我不确定我能做到多清楚:直接注入您当前正在注入的对象的提供者,如答案中的链接所示。
【解决方案2】:

我使用 dagger.Lazy 和 Hilt 使这成为可能(几乎与 dagger 相同 - 它在引擎盖下使用 dagger)。但小心点。循环依赖可能是糟糕设计的结果,并可能导致许多问题。这是一个例子:

class Cls1 @Inject constructor() {
    @Inject lateinit var cls2: dagger.Lazy<Cls2>
}

class Cls2 @Inject constructor() {
    @Inject lateinit var cls1: dagger.Lazy<Cls1>
}

@HiltAndroidApp
class ApplicationClass: Application() {
    @Inject lateinit var cls1: Cls1
    @Inject lateinit var cls2: Cls2

    override fun onCreate() {
        super.onCreate()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-17
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    相关资源
    最近更新 更多