简体   繁体   English

Android dagger 依赖循环

[英]Android dagger dependency cycle

I have 2 dependencies with the same Scope that require of each other.我有 2 个具有相同作用域的依赖项,它们彼此需要。

My dependencies are domain services with different methods ( each method a different business case).我的依赖项是具有不同方法的域服务(每种方法都有不同的业务案例)。 some business cases might use methods from another domain.一些业务案例可能使用来自另一个领域的方法。

In order to do this I need domain1 to be available for domain2 and vice versa.为了做到这一点,我需要 domain1 可用于 domain2,反之亦然。

but when i do this i get a dependency cycle compilation error.但是当我这样做时,我得到一个依赖循环编译错误。 after googling for some time i found that in order to overcome this issue i must inject one of the dependencies with the @Inject annotation instead of a constructor parameter in the @Module.在谷歌搜索一段时间后,我发现为了解决这个问题,我必须使用 @Inject 注释而不是 @Module 中的构造函数参数注入依赖项之一。

when i try this the code compiles but dagger is not injecting the second dependency at all.当我尝试这个代码编译但匕首根本没有注入第二个依赖项。

is there a way to achieve what i want with Dagger?有没有办法用 Dagger 实现我想要的?

Your problem: AClass has a constructor dependency on BClass, which has a constructor dependency on AClass. 您的问题: AClass对BClass有一个构造函数依赖,它对AClass有一个构造函数依赖。 Even without Dagger, this wouldn't work: If they depend on each other, which would you create first? 即使没有Dagger,这也行不通:如果他们相互依赖,你会先创造哪个?

Your attempted solution: If you create one of your classes (BClass) using new , and it no longer has an @Inject -annotated constructor, you could wait until after AClass is constructed to populate your BClass instance. 您尝试的解决方案:如果使用new创建其中一个类(BClass),并且它不再具有@Inject -annotated构造函数,则可以等到构造完AClass之后再填充BClass实例。 However, if you create an object using new , you'll need to inject it by passing it into a members-injection method or MembersInjector<BClass> object. 但是,如果使用new创建对象,则需要通过将其传递给MembersInjector<BClass> -injection方法或MembersInjector<BClass>对象来注入它。 You'll also need to make sure that this happens outside of the @Provides method (because the whole reason @Provides is being called is so you can construct a value to pass into AClass's constructor). 你还需要确保在@Provides方法之外发生这种情况(因为调用@Provides的原因是你可以构造一个值来传递给AClass的构造函数)。 This is fragile and fairly ugly. 这很脆弱,相当丑陋。

My suggestion: Use indirection via Provider . 我的建议: 通过Provider使用间接 Have AClass inject Provider<BClass> , or BClass inject Provider<AClass> , or both. 让AClass注入Provider<BClass> ,或BClass注入Provider<AClass> ,或两者兼而有之。 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. 只要你不在构造函数中调用get ,你就可以让Dagger创建AClass并推迟创建BClass直到你需要它为止。 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; 您不需要额外的配置就可以为您绑定在Component中的任何类T注入Provider<T>Lazy<T> ; see "Bindings in the Graph" in the User's Guide for the full list of available injections. 有关可用进样的完整列表,请参阅“用户指南”中的“图表中的结合”

I made this possible using dagger.Lazy and Hilt (almost same as dagger - it is using dagger under the hood).我使用 dagger.Lazy 和 Hilt(几乎与 dagger 相同 - 它在引擎盖下使用 dagger)使这成为可能。 But be careful.不过要小心。 Circular dependency may be result of bad design and can lead to many problems.循环依赖可能是糟糕设计的结果,并可能导致许多问题。 Here is example:这是示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM