The problem with cyclic injects checker
See original GitHub issueHello! Unfortunately, I got an unexpected crash with toothpick.
How to reproduce the crash
val parentScope = KTP.openScope("App")
val childScope = KTP.openScopes("App", "Child")
childScope.installModules(module {
bind(...) // here is I bind some isolated(internal) instances that I need only in "Child" scope
bind(IFace::class.java).to(Face::class.java).singleton() // also I bind some Interface to provide outside (like dagger's component)
})
// I want to provide some interface from my child scope to parent scope
parentScope.installModules(module {
bind(IFace::class.java).toProviderInstance { childScope.getInstance(IFace::class.java) }.providesSingleton()
})
this code throws
Class xxx.xxx.IFace creates a cycle:
===============================
|| ||
\/ ||
xxx.xxx.IFace ||
|| ||
===============================
this code is working, but it creates instance immediately
bind(IFace::class.java).toInstance(childScope.getInstance(IFace::class.java)).singleton()
If I remove any cycles checking from toothpick, everything is working as I expected
the problem with this code from RuntimeCheckOnConfiguration.java
final LinkedHashSet<Pair> linkedHashSet = cycleDetectionStack.get();
if (linkedHashSet.contains(pair)) { // pair = IFace|null
throw new CyclicDependencyException(Pair.getClassList(linkedHashSet), clazz);
}
we are trying to get IFace
instance from child
scope, but we already trying to get it from parent scope
cycles checking code can’t understand it 😃
Issue Analytics
- State:
- Created 3 years ago
- Comments:6
Top Results From Across the Web
Dependency Injection With Cyclic Dependencies | The Miners
When using DI we isolate the construction of dependencies in a single place we call composition root or container and then the code...
Read more >Circular Dependencies in Spring - Baeldung
A quick writeup on dealing with circular dependencies in Spring: how they occur and several ways to work around them.
Read more >Circular Dependencies in Dependency Injection - Medium
A description of how we solved a circular dependency in our dependency injection, and some of the software principles involved.
Read more >Dealing With Circular Dependency Injection References
Your main problem there is you are breaking dependency injection by manually injecting dependencies. It does solve the DI blowing up, but IMO ......
Read more >NG0200: Circular dependency in DI detected while ... - Angular
Debugging the errorlink ... Use the call stack to determine where the cyclical dependency exists. You will be able to see if any...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Here is I want to bind an interface without creating of instance right now. Because it’s possible that IAdsManager will never instantiate because we don’t open some screen. For example, I open some screen (ViewModel), with injected IAdsManager, and then I call
IAdsManager.init()
to do network request. I want to do the job(create an instance of a manager) when it needed, for example when ViewModel is instantiated.IAdsManager - it’s just for example. Overall I’m talking about an approach to solve this problem.
This code is solving the problem, but it creates the instance right in the app. I don’t like it.
I agree, and I think the toothpick is not designed to solve my problem clearly.
fix https://github.com/stephanenicolas/toothpick/pull/428