mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Fix autowiring deep circular dependencies
This commit is contained in:
parent
b88745130a
commit
b66b9d5def
|
@ -123,12 +123,11 @@ assert(instance.dependency !is null);
|
|||
If an interface is to be autowired, you must register a concrete class by interface. Any class registered by concrete type can only be injected when a dependency on a concrete type is autowired.
|
||||
|
||||
###Circular dependencies
|
||||
Poodinis can autowire circular dependencies to a certain degree. See known issues for current limitations on this. For now you might want to consider if your design really needs circular dependencies.
|
||||
Poodinis can autowire circular dependencies when they are registered with singleInstance or existingInstance registration scopes. See Known issues for the limitations on newInstance scopes.
|
||||
|
||||
Known issues
|
||||
------------
|
||||
* Circular dependencies down the dependency tree still fails if the dependencies don't refer to the type being resolved initially.
|
||||
* Due to preventive measures of recursion issues in circular dependencies, registrations which are supposed to yield new instances will not autowire classes for which a recursive resolve is detected.
|
||||
* Due to preventive measures of recursion issues in circular dependencies, registrations which are supposed to yield new instances will not autowire classes for which a circular dependency is detected. A new instance will be resolved but the instance's members will not be autowired.
|
||||
|
||||
Future Work
|
||||
-----------
|
||||
|
|
|
@ -9,6 +9,7 @@ module poodinis.container;
|
|||
|
||||
import std.string;
|
||||
import std.array;
|
||||
import std.algorithm;
|
||||
|
||||
public import poodinis.registration;
|
||||
public import poodinis.autowire;
|
||||
|
@ -31,7 +32,7 @@ class Container {
|
|||
|
||||
private Registration[TypeInfo] registrations;
|
||||
|
||||
private Registration* registrationBeingResolved;
|
||||
private Registration*[] autowireStack;
|
||||
|
||||
public Registration register(ConcreteType)() {
|
||||
return register!(ConcreteType, ConcreteType)();
|
||||
|
@ -54,18 +55,12 @@ class Container {
|
|||
throw new ResolveException("Type not registered.", resolveType);
|
||||
}
|
||||
|
||||
auto initialResolve = false;
|
||||
if (registrationBeingResolved is null) {
|
||||
registrationBeingResolved = registration;
|
||||
initialResolve = true;
|
||||
}
|
||||
|
||||
RegistrationType instance = cast(RegistrationType) registration.getInstance();
|
||||
if (initialResolve || registrationBeingResolved !is registration) {
|
||||
|
||||
if (!autowireStack.canFind(registration)) {
|
||||
autowireStack ~= registration;
|
||||
this.autowire!(RegistrationType)(instance);
|
||||
}
|
||||
if (initialResolve) {
|
||||
registrationBeingResolved = null;
|
||||
autowireStack.popBack();
|
||||
}
|
||||
|
||||
return instance;
|
||||
|
|
|
@ -58,6 +58,21 @@ version(unittest) {
|
|||
public Eenie eenie;
|
||||
}
|
||||
|
||||
class Ittie {
|
||||
@Autowire
|
||||
public Bittie bittie;
|
||||
}
|
||||
|
||||
class Bittie {
|
||||
@Autowire
|
||||
public Banana banana;
|
||||
}
|
||||
|
||||
class Banana {
|
||||
@Autowire
|
||||
public Bittie bittie;
|
||||
}
|
||||
|
||||
// Test register concrete type
|
||||
unittest {
|
||||
auto container = new Container();
|
||||
|
@ -185,4 +200,28 @@ version(unittest) {
|
|||
|
||||
assert(eenie.meenie.moe.eenie is eenie, "Autowiring third-degree circular dependency failed");
|
||||
}
|
||||
|
||||
// Test autowiring deep circular dependencies
|
||||
unittest {
|
||||
auto container = new Container();
|
||||
container.register!Ittie;
|
||||
container.register!Bittie;
|
||||
container.register!Banana;
|
||||
|
||||
auto ittie = container.resolve!Ittie;
|
||||
|
||||
assert(ittie.bittie is ittie.bittie.banana.bittie, "Autowiring deep dependencies failed.");
|
||||
}
|
||||
|
||||
// Test autowiring deep circular dependencies with newInstance scope does not autowire new instance second time
|
||||
unittest {
|
||||
auto container = new Container();
|
||||
container.register!(Ittie).newInstance();
|
||||
container.register!(Bittie).newInstance();
|
||||
container.register!(Banana).newInstance();
|
||||
|
||||
auto ittie = container.resolve!Ittie;
|
||||
|
||||
assert(ittie.bittie.banana.bittie.banana is null, "Autowiring deep dependencies with newInstance scope autowired a reoccuring type.");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue