Autowire dependencies using autowired registrations instead of letting the container handle it

This fixes known issue "Resolving a class registered by supertype..."
This commit is contained in:
Mike Bierlee 2015-01-25 21:04:17 +01:00
parent 5ebb5805cf
commit 36992c633a
3 changed files with 29 additions and 8 deletions

View file

@ -141,7 +141,7 @@ If you registered multiple concrete types to the same supertype and you do not r
Known issues Known issues
------------ ------------
* Resolving a class registered by supertype or interface will only autowire the members inherited from its supertypes and in the case of interfaces none at all. To work around this issue, use a qualifier. Alternatively you could immediately resolve all registrations once by qualifiers after registering everything. See "[Registering and resolving using qualifiers](#Registering and resolving using qualifiers)". None! Found one? Let us know on github.
Future Work Future Work
----------- -----------

View file

@ -61,7 +61,7 @@ class DependencyContainer {
} }
} }
Registration newRegistration = new Registration(registeredType, concreteType); AutowiredRegistration!ConcreteType newRegistration = new AutowiredRegistration!ConcreteType(registeredType, this);
newRegistration.singleInstance(); newRegistration.singleInstance();
registrations[registeredType] ~= newRegistration; registrations[registeredType] ~= newRegistration;
return newRegistration; return newRegistration;
@ -95,12 +95,16 @@ class DependencyContainer {
} }
Registration registration = getQualifiedRegistration(resolveType, qualifierType, *candidates); Registration registration = getQualifiedRegistration(resolveType, qualifierType, *candidates);
QualifierType instance = cast(QualifierType) registration.getInstance(); QualifierType instance;
if (!autowireStack.canFind(registration)) { if (!autowireStack.canFind(registration)) {
autowireStack ~= registration; autowireStack ~= registration;
this.autowire!(QualifierType)(instance); instance = cast(QualifierType) registration.getInstance(new AutowireInstantiationContext());
autowireStack.popBack(); autowireStack.popBack();
} else {
auto autowireContext = new AutowireInstantiationContext();
autowireContext.autowireInstance = false;
instance = cast(QualifierType) registration.getInstance(autowireContext);
} }
return instance; return instance;

View file

@ -90,6 +90,11 @@ version(unittest) {
class Red : Color { class Red : Color {
} }
class Spiders {
@Autowire
public TestInterface testMember;
}
// Test register concrete type // Test register concrete type
unittest { unittest {
auto container = new DependencyContainer(); auto container = new DependencyContainer();
@ -242,15 +247,16 @@ version(unittest) {
assert(ittie.bittie.banana.bittie.banana is null, "Autowiring deep dependencies with newInstance scope autowired a reoccuring type."); assert(ittie.bittie.banana.bittie.banana is null, "Autowiring deep dependencies with newInstance scope autowired a reoccuring type.");
} }
// Test autowiring type registered by interface fails (BUG test case) // Test autowiring type registered by interface
unittest { unittest {
auto container = new DependencyContainer(); auto container = new DependencyContainer();
container.register!Banana; container.register!Banana;
container.register!Bittie;
container.register!(SuperInterface, SuperImplementation); container.register!(SuperInterface, SuperImplementation);
SuperImplementation superInstance = cast(SuperImplementation) container.resolve!SuperInterface; SuperImplementation superInstance = cast(SuperImplementation) container.resolve!SuperInterface;
assert(superInstance.banana is null, "Autowire instance which was resolved by interface type, which was not expected to be possible"); assert(!(superInstance.banana is null), "Instance which was resolved by interface type was not autowired.");
} }
// Test reusing a container after clearing all registrations // Test reusing a container after clearing all registrations
@ -316,4 +322,15 @@ version(unittest) {
assert(blueInstance !is null, "Resolved blue instance to null"); assert(blueInstance !is null, "Resolved blue instance to null");
assert(redInstance !is null, "Resolved red instance to null"); assert(redInstance !is null, "Resolved red instance to null");
} }
// Test autowire of unqualified member typed by interface.
unittest {
auto container = new DependencyContainer();
container.register!Spiders;
container.register!(TestInterface, TestClass);
auto instance = container.resolve!Spiders;
assert(!(instance is null), "Container failed to autowire member by interface");
}
} }