Whether circular dependencies work depends on the order objects are retrieved from the injector
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 1.7k
- Avg merge
- 11m
- Merged PRs (30d)
- 2
Description
For example:
``` java
class A {
@Inject
A(B b) {
}
}
class B {
@Inject
A a;
}
class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(A.class).in(Singleton.class);
bind(B.class).in(Singleton.class);
}
}
public class FooTest {
@Test
public void testAFirst() {
// Fails
Guice.createInjector(new MyModule()).getInstance(A.class);
}
@Test
public void testBFirst() {
// Passes
Guice.createInjector(new MyModule()).getInstance(B.class);
}
@Test
public void testProduction() {
// Fails for me, probably not deterministic?
Guice.createInjector(Stage.PRODUCTION, new MyModule());
}
}
```
I think I understand why this happens, but I don't think it's particularly desirable. In fact, when it does "work," we're still passing a partially-initialized `B` instance to `A`'s constructor, which could be problematic if it tries to _use_ `B` instead of just storing it in a field.
My proposed resolution is a new flag `binder().disableCircularDependencies()` that completely disallows dependency cycles (unless broken by a `Provider`). Or possibly `binder().disableCircularClassDependencies()` if we want the option to allow circular dependencies through interfaces, since those work due to proxying.
Contributor guide
Assessment
This issue has not been assessed yet.