Android 匕首依赖循环

Android dagger dependency cycle

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

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

为此,我需要域 1 可用于域 2,反之亦然。

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

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

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

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

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

我的建议:使用indirection via Provider. Have AClass inject Provider<BClass>, or BClass inject Provider<AClass>, or both. As long as you don't call get within the constructor, you'll allow Dagger to create AClass and defer the creation of BClass until you need it. You need no additional configuration in order to inject a Provider<T> or Lazy<T> for any class T you've bound in your Component; see "Bindings in the Graph" in the User's Guide获取可用注入的完整列表。

我使用 dagger.Lazy 和 Hilt(几乎与匕首相同 - 它在引擎盖下使用匕首)使这成为可能。不过要小心。循环依赖可能是不良设计的结果,并可能导致许多问题。这是示例:

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()
    }
}