Hello, I'm having this stacktracke while I'm tryin...
# koin
o
Hello, I'm having this stacktracke while I'm trying to work with api/impl module
Copy code
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ......, PID: 29490
    java.lang.StackOverflowError: stack size 8MB
        at kotlin.reflect.jvm.internal.pcollections.IntTree.get(IntTree.java:93)
        at kotlin.reflect.jvm.internal.pcollections.IntTree.get(IntTree.java:93)
        at kotlin.reflect.jvm.internal.pcollections.IntTreePMap.get(IntTreePMap.java:42)
        at kotlin.reflect.jvm.internal.pcollections.HashPMap.getEntries(HashPMap.java:85)
        at kotlin.reflect.jvm.internal.pcollections.HashPMap.get(HashPMap.java:51)
        at kotlin.reflect.jvm.internal.KClassCacheKt.getOrCreateKotlinClass(kClassCache.kt:32)
        at kotlin.reflect.jvm.internal.ReflectionFactoryImpl.getOrCreateKotlinClass(ReflectionFactoryImpl.java:50)
        at kotlin.jvm.internal.Reflection.getOrCreateKotlinClass(Reflection.java:59)
        at org.koin.android.ext.koin.ModuleExtKt.androidApplication(ModuleExt.kt:54)
Is there a way that I can debug to know what's happening?
What I’m trying to do
Copy code
factory<FeatureA> {
    FeatureAImpl(
        featureB = get(),
    )
}

factory<FeatureB> {
    FeatureBImpl(
        application = androidApplication(),
        featureA = get(),
    )
}
b
A cyclic loop no ? FeatA needs FeatB, and FeatB needs FeatA ?
o
yep, apparently is there a way to handle it?
b
No idea, seems not a good idea to have cyclic dependencies
They are coupled, should not
👌 1
a
there was a cycle dependency detector in previous 2.1.x, for performance consideration I’v removed it. But worth to consider it again later 🤔
👍🏽 1
👍 2
n
It is better to break the cycle, but you can sometime work around it using delayed injection:
Copy code
factory<FeatureA> {
     FeatureAImpl(
         featureBProvider = { get<FeatureB>() },
     )
 }
Copy code
factory<FeatureB> {
     FeatureBImpl(
         application = androidApplication(),
         featureAProvider = { get<FeatureA>() },
     )
 }
Both feature implementation must be modified to take a
() -> Feature
instead of a
Feature
though
b
By “delaying” the injection, how can you be sure you won’t have the same issue again ? ie. FeatA is really fat, FeatB isn’t, you may encounter the issue again no ? (bad timing for example)
n
You cannot be sure, that's why decoupling is better. This pattern mostly work if the injection is needed to react to some callbacks, like an onClickListener
b
Ok, thx for the confirmation
a
You can even use
inject()
in the DSL to have a Lazy<T>
2
o
Thank you, mates I ended up changing my implementation to not have this cycle dependency, I believe it would be safer 😅
👍 2