diff --git a/README.md b/README.md index c13a66e..391d699 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ void main() { auto container = DependencyContainer.getInstance(); container.register!DataWriter; container.register!(Database, RelationalDatabase); - + auto writer = container.resolve!DataWriter; } ``` @@ -79,7 +79,7 @@ With dependency scopes, you can control how a dependency is resolved. The scope * Resolve a dependency using a single instance (default): ```d -container.register!(ExampleClass).singleInstance(); +container.register!(ExampleClass).singleInstance(); ``` * Resolve a dependency with a new instance each time it is resolved: @@ -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 ----------- diff --git a/source/poodinis/container.d b/source/poodinis/container.d index d46e378..827ce3f 100644 --- a/source/poodinis/container.d +++ b/source/poodinis/container.d @@ -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; diff --git a/test/poodinis/containertest.d b/test/poodinis/containertest.d index 9153c6b..1632655 100644 --- a/test/poodinis/containertest.d +++ b/test/poodinis/containertest.d @@ -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"); + } }