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
------------
* 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
-----------

View file

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

View file

@ -90,6 +90,11 @@ version(unittest) {
class Red : Color {
}
class Spiders {
@Autowire
public TestInterface testMember;
}
// Test register concrete type
unittest {
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.");
}
// Test autowiring type registered by interface fails (BUG test case)
// Test autowiring type registered by interface
unittest {
auto container = new DependencyContainer();
container.register!Banana;
container.register!Bittie;
container.register!(SuperInterface, SuperImplementation);
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
@ -316,4 +322,15 @@ version(unittest) {
assert(blueInstance !is null, "Resolved blue 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");
}
}