简体   繁体   中英

Android dagger dependency cycle

I have 2 dependencies with the same Scope that require of each other.

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.

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.

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?

Your problem: AClass has a constructor dependency on BClass, which has a constructor dependency on AClass. Even without Dagger, this wouldn't work: If they depend on each other, which would you create first?

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. 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. 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). This is fragile and fairly ugly.

My suggestion: Use 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 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). 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()
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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