安卓匕首依赖周期



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

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

为了做到这一点,我需要域 1 可用于域 2,反之亦然。

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

当我尝试这样做时,代码会编译,但 Dagger 根本没有注入第二个依赖项。

有没有办法用dagger实现我想要的东西?

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

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

我的建议:通过提供程序使用间接寻址。让 AClass 注入Provider<BClass>,或 BClass 注入Provider<AClass>,或两者兼而有之。只要您不在构造函数中调用get,您就会允许 Dagger 创建 AClass,并将 BClass 的创建推迟到您需要它。您无需额外的配置即可为组件中绑定的任何类 T 注入Provider<T>Lazy<T>;有关可用注入的完整列表,请参阅用户指南中的"图中的绑定"。

我用dagger使这成为可能。懒惰和剑柄(几乎与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()
}
}

最新更新