From 9e5a27d046413654d967603240d805848bfc9961 Mon Sep 17 00:00:00 2001 From: Mike Bierlee Date: Mon, 8 Aug 2016 22:17:17 +0200 Subject: [PATCH] Deprecate singleton factory method The factory method encourages misuse of dependency injection (by using it as a service locator). Removing the factory method forces the user to make this choice deliberately. --- CHANGES.md | 3 + README.md | 2 +- TUTORIAL.md | 7 +- example/annotations/app.d | 2 +- example/applicationcontext/app.d | 2 +- example/arraycompletion/app.d | 2 +- example/qualifiers/app.d | 2 +- example/quickstart/app.d | 2 +- example/registeronresolve/app.d | 2 +- source/poodinis/container.d | 3 +- test/poodinis/autowiretest.d | 486 +++++++++++++++---------------- test/poodinis/containertest.d | 96 +++--- test/poodinis/contexttest.d | 10 +- 13 files changed, 311 insertions(+), 308 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 861fbd2..4bd97c6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,9 @@ Poodinis Changelog * REMOVE deprecated registration options. They are still available in properly cased forms. * REMOVE deprecated register() and resolve() methods which accept variadics and arrays for options. Since registration and resolve options have become bitfields, you should specify them with logical ANDs. +* DEPRECATE DependencyContainer.getInstance(). To properly make use of inversion of control, one should only +create the dependency container once during set-up and then completly rely on injection. See examples for +proper usage. You can still create your own singleton factory (method) if this is crucial to your design. **Version 6.3.0** * CHANGE registration and resolve options to be supplied using bit flags instead. (Thanks to tmccombs) diff --git a/README.md b/README.md index bfeadb3..21e2511 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ class DataWriter { } void main() { - auto dependencies = DependencyContainer.getInstance(); + auto dependencies = new shared DependencyContainer(); dependencies.register!DataWriter; dependencies.register!(Database, RelationalDatabase); diff --git a/TUTORIAL.md b/TUTORIAL.md index b15140c..a6363ea 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -6,11 +6,10 @@ The container ------------- To register a class, a new dependency container must be instantiated: ```d -// Register a private container -shared(DependencyContainer) dependencies = new DependencyContainer(); -// Or use the singleton container -dependencies = DependencyContainer.getInstance(); +// Create a shared container +auto dependencies = new shared DependencyContainer(); ``` +A shared dependency container is thread-safe and resolves the same dependencies across all threads. ###Registering dependencies To make dependencies available, they have to be registered: ```d diff --git a/example/annotations/app.d b/example/annotations/app.d index b3a49b5..8733c25 100644 --- a/example/annotations/app.d +++ b/example/annotations/app.d @@ -53,7 +53,7 @@ class SecurityManager { } void main() { - auto dependencies = DependencyContainer.getInstance(); + auto dependencies = new shared DependencyContainer(); dependencies.register!SuperSecurityDevice; // Registered with the default "Single instance" scope dependencies.register!SecurityManager; diff --git a/example/applicationcontext/app.d b/example/applicationcontext/app.d index 71b0384..5773d8a 100644 --- a/example/applicationcontext/app.d +++ b/example/applicationcontext/app.d @@ -60,7 +60,7 @@ class ExampleApplicationContext : ApplicationContext { } void main() { - auto container = DependencyContainer.getInstance(); + auto container = new shared DependencyContainer(); container.registerContext!ExampleApplicationContext; auto townSquare = container.resolve!TownSquare; diff --git a/example/arraycompletion/app.d b/example/arraycompletion/app.d index bdcd47e..01faf5a 100644 --- a/example/arraycompletion/app.d +++ b/example/arraycompletion/app.d @@ -43,7 +43,7 @@ class PieEater { } void main() { - auto dependencies = DependencyContainer.getInstance(); + auto dependencies = new shared DependencyContainer(); dependencies.register!(Pie, BlueBerryPie); dependencies.register!(Pie, ApplePie); dependencies.register!(Pie, CardboardBoxPie); diff --git a/example/qualifiers/app.d b/example/qualifiers/app.d index 9edd370..32a8949 100644 --- a/example/qualifiers/app.d +++ b/example/qualifiers/app.d @@ -44,7 +44,7 @@ class HybridCar { } void main() { - auto dependencies = DependencyContainer.getInstance(); + auto dependencies = new shared DependencyContainer(); dependencies.register!HybridCar; dependencies.register!(Engine, FuelEngine); diff --git a/example/quickstart/app.d b/example/quickstart/app.d index 8d2ac87..02d3823 100644 --- a/example/quickstart/app.d +++ b/example/quickstart/app.d @@ -16,7 +16,7 @@ class DataWriter { } void main() { - auto dependencies = DependencyContainer.getInstance(); + auto dependencies = new shared DependencyContainer(); dependencies.register!DataWriter; dependencies.register!(Database, RelationalDatabase); diff --git a/example/registeronresolve/app.d b/example/registeronresolve/app.d index 113080e..f27f776 100644 --- a/example/registeronresolve/app.d +++ b/example/registeronresolve/app.d @@ -26,7 +26,7 @@ class Orchestra { } void main() { - auto dependencies = DependencyContainer.getInstance(); + auto dependencies = new shared DependencyContainer(); /* * By using the resolve option "registerBeforeResolving" you can register the resolved class diff --git a/source/poodinis/container.d b/source/poodinis/container.d index b600fc0..0258c98 100644 --- a/source/poodinis/container.d +++ b/source/poodinis/container.d @@ -389,8 +389,9 @@ synchronized class DependencyContainer { /** * Returns a global singleton instance of a dependency container. + * Deprecated: create new instance with new keyword or implement your own singleton factory (method) */ - public static shared(DependencyContainer) getInstance() { + deprecated public static shared(DependencyContainer) getInstance() { static shared DependencyContainer instance; if (instance is null) { instance = new DependencyContainer(); diff --git a/test/poodinis/autowiretest.d b/test/poodinis/autowiretest.d index 432deb4..b9e643c 100644 --- a/test/poodinis/autowiretest.d +++ b/test/poodinis/autowiretest.d @@ -1,243 +1,243 @@ -/** - * Poodinis Dependency Injection Framework - * Copyright 2014-2016 Mike Bierlee - * This software is licensed under the terms of the MIT license. - * The full terms of the license can be found in the LICENSE file. - */ - -import poodinis; - -import std.exception; - -version(unittest) { - class ComponentA {} - - class ComponentB { - public @Autowire ComponentA componentA; - } - - interface InterfaceA {} - - class ComponentC : InterfaceA {} - - class ComponentD { - public @Autowire InterfaceA componentC = null; - private @Autowire InterfaceA privateComponentC = null; - } - - class DummyAttribute{}; - - class ComponentE { - @DummyAttribute - public ComponentC componentC; - } - - class ComponentDeclarationCocktail { - alias noomer = int; - - @Autowire - public ComponentA componentA; - - public void doesNothing() { - } - - ~this(){ - } - } - - class ComponentX : InterfaceA {} - - class ComponentZ : ComponentB { - } - - class MonkeyShine { - @Autowire!ComponentX - public InterfaceA component; - } - - class BootstrapBootstrap { - @Autowire!ComponentX - public InterfaceA componentX; - - @Autowire!ComponentC - public InterfaceA componentC; - } - - class LordOfTheComponents { - @Autowire - public InterfaceA[] components; - } - class ComponentCharlie { - @Autowire - @AssignNewInstance - public ComponentA componentA; - } - - class OuttaTime { - @Autowire - @OptionalDependency - public InterfaceA interfaceA; - - @Autowire - @OptionalDependency - public ComponentA componentA; - - @Autowire - @OptionalDependency - public ComponentC[] componentCs; - } - - // Test autowiring concrete type to existing instance - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!ComponentA; - auto componentB = new ComponentB(); - container.autowire(componentB); - assert(componentB !is null, "Autowirable dependency failed to autowire"); - } - - // Test autowiring interface type to existing instance - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!(InterfaceA, ComponentC); - auto componentD = new ComponentD(); - container.autowire(componentD); - assert(componentD.componentC !is null, "Autowirable dependency failed to autowire"); - } - - // Test autowiring private members - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!(InterfaceA, ComponentC); - auto componentD = new ComponentD(); - container.autowire(componentD); - assert(componentD.privateComponentC is componentD.componentC, "Autowire private dependency failed"); - } - - // Test autowiring will only happen once - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!(InterfaceA, ComponentC).newInstance(); - auto componentD = new ComponentD(); - container.autowire(componentD); - auto expectedComponent = componentD.componentC; - container.autowire(componentD); - auto actualComponent = componentD.componentC; - assert(expectedComponent is actualComponent, "Autowiring the second time wired a different instance"); - } - - // Test autowiring unregistered type - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - auto componentD = new ComponentD(); - assertThrown!(ResolveException)(container.autowire(componentD), "Autowiring unregistered type should throw ResolveException"); - } - - // Test autowiring member with non-autowire attribute does not autowire - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - auto componentE = new ComponentE(); - container.autowire(componentE); - assert(componentE.componentC is null, "Autowiring should not occur for members with attributes other than @Autowire"); - } - - // Test autowire class with alias declaration - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!ComponentA; - auto componentDeclarationCocktail = new ComponentDeclarationCocktail(); - - container.autowire(componentDeclarationCocktail); - - assert(componentDeclarationCocktail.componentA !is null, "Autowiring class with non-assignable declarations failed"); - } - - // Test autowire class with qualifier - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!(InterfaceA, ComponentC); - container.register!(InterfaceA, ComponentX); - auto componentX = container.resolve!(InterfaceA, ComponentX); - - auto monkeyShine = new MonkeyShine(); - container.autowire(monkeyShine); - - assert(monkeyShine.component is componentX, "Autowiring class with qualifier failed"); - } - - // Test autowire class with multiple qualifiers - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!(InterfaceA, ComponentC); - container.register!(InterfaceA, ComponentX); - auto componentC = container.resolve!(InterfaceA, ComponentC); - auto componentX = container.resolve!(InterfaceA, ComponentX); - - auto bootstrapBootstrap = new BootstrapBootstrap(); - container.autowire(bootstrapBootstrap); - - assert(bootstrapBootstrap.componentX is componentX, "Autowiring class with multiple qualifiers failed"); - assert(bootstrapBootstrap.componentC is componentC, "Autowiring class with multiple qualifiers failed"); - } - - // Test getting instance from autowired registration will autowire instance - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!ComponentA; - - auto registration = new AutowiredRegistration!ComponentB(typeid(ComponentB), container).singleInstance(); - auto instance = cast(ComponentB) registration.getInstance(new AutowireInstantiationContext()); - - assert(instance.componentA !is null); - } - - // Test autowiring a dynamic array with all qualified types - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!(InterfaceA, ComponentC); - container.register!(InterfaceA, ComponentX); - - auto lord = new LordOfTheComponents(); - container.autowire(lord); - - assert(lord.components.length == 2, "Dynamic array was not autowired"); - } - - // Test autowiring new instance of singleinstance registration with newInstance UDA - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!ComponentA; - - auto regularComponentA = container.resolve!ComponentA; - auto charlie = new ComponentCharlie(); - - container.autowire(charlie); - - assert(charlie.componentA !is regularComponentA, "Autowiring class with AssignNewInstance did not yield a different instance"); - } - - // Test autowiring members from base class - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - container.register!ComponentA; - container.register!ComponentB; - container.register!ComponentZ; - - auto instance = new ComponentZ(); - container.autowire(instance); - - assert(instance.componentA !is null); - } - - // Test autowiring optional depenencies - unittest { - shared(DependencyContainer) container = new DependencyContainer(); - auto instance = new OuttaTime(); - - container.autowire(instance); - - assert(instance.interfaceA is null); - assert(instance.componentA is null); - assert(instance.componentCs is null); - } -} +/** + * Poodinis Dependency Injection Framework + * Copyright 2014-2016 Mike Bierlee + * This software is licensed under the terms of the MIT license. + * The full terms of the license can be found in the LICENSE file. + */ + +import poodinis; + +import std.exception; + +version(unittest) { + class ComponentA {} + + class ComponentB { + public @Autowire ComponentA componentA; + } + + interface InterfaceA {} + + class ComponentC : InterfaceA {} + + class ComponentD { + public @Autowire InterfaceA componentC = null; + private @Autowire InterfaceA privateComponentC = null; + } + + class DummyAttribute{}; + + class ComponentE { + @DummyAttribute + public ComponentC componentC; + } + + class ComponentDeclarationCocktail { + alias noomer = int; + + @Autowire + public ComponentA componentA; + + public void doesNothing() { + } + + ~this(){ + } + } + + class ComponentX : InterfaceA {} + + class ComponentZ : ComponentB { + } + + class MonkeyShine { + @Autowire!ComponentX + public InterfaceA component; + } + + class BootstrapBootstrap { + @Autowire!ComponentX + public InterfaceA componentX; + + @Autowire!ComponentC + public InterfaceA componentC; + } + + class LordOfTheComponents { + @Autowire + public InterfaceA[] components; + } + class ComponentCharlie { + @Autowire + @AssignNewInstance + public ComponentA componentA; + } + + class OuttaTime { + @Autowire + @OptionalDependency + public InterfaceA interfaceA; + + @Autowire + @OptionalDependency + public ComponentA componentA; + + @Autowire + @OptionalDependency + public ComponentC[] componentCs; + } + + // Test autowiring concrete type to existing instance + unittest { + auto container = new shared DependencyContainer(); + container.register!ComponentA; + auto componentB = new ComponentB(); + container.autowire(componentB); + assert(componentB !is null, "Autowirable dependency failed to autowire"); + } + + // Test autowiring interface type to existing instance + unittest { + auto container = new shared DependencyContainer(); + container.register!(InterfaceA, ComponentC); + auto componentD = new ComponentD(); + container.autowire(componentD); + assert(componentD.componentC !is null, "Autowirable dependency failed to autowire"); + } + + // Test autowiring private members + unittest { + auto container = new shared DependencyContainer(); + container.register!(InterfaceA, ComponentC); + auto componentD = new ComponentD(); + container.autowire(componentD); + assert(componentD.privateComponentC is componentD.componentC, "Autowire private dependency failed"); + } + + // Test autowiring will only happen once + unittest { + auto container = new shared DependencyContainer(); + container.register!(InterfaceA, ComponentC).newInstance(); + auto componentD = new ComponentD(); + container.autowire(componentD); + auto expectedComponent = componentD.componentC; + container.autowire(componentD); + auto actualComponent = componentD.componentC; + assert(expectedComponent is actualComponent, "Autowiring the second time wired a different instance"); + } + + // Test autowiring unregistered type + unittest { + auto container = new shared DependencyContainer(); + auto componentD = new ComponentD(); + assertThrown!(ResolveException)(container.autowire(componentD), "Autowiring unregistered type should throw ResolveException"); + } + + // Test autowiring member with non-autowire attribute does not autowire + unittest { + auto container = new shared DependencyContainer(); + auto componentE = new ComponentE(); + container.autowire(componentE); + assert(componentE.componentC is null, "Autowiring should not occur for members with attributes other than @Autowire"); + } + + // Test autowire class with alias declaration + unittest { + auto container = new shared DependencyContainer(); + container.register!ComponentA; + auto componentDeclarationCocktail = new ComponentDeclarationCocktail(); + + container.autowire(componentDeclarationCocktail); + + assert(componentDeclarationCocktail.componentA !is null, "Autowiring class with non-assignable declarations failed"); + } + + // Test autowire class with qualifier + unittest { + auto container = new shared DependencyContainer(); + container.register!(InterfaceA, ComponentC); + container.register!(InterfaceA, ComponentX); + auto componentX = container.resolve!(InterfaceA, ComponentX); + + auto monkeyShine = new MonkeyShine(); + container.autowire(monkeyShine); + + assert(monkeyShine.component is componentX, "Autowiring class with qualifier failed"); + } + + // Test autowire class with multiple qualifiers + unittest { + auto container = new shared DependencyContainer(); + container.register!(InterfaceA, ComponentC); + container.register!(InterfaceA, ComponentX); + auto componentC = container.resolve!(InterfaceA, ComponentC); + auto componentX = container.resolve!(InterfaceA, ComponentX); + + auto bootstrapBootstrap = new BootstrapBootstrap(); + container.autowire(bootstrapBootstrap); + + assert(bootstrapBootstrap.componentX is componentX, "Autowiring class with multiple qualifiers failed"); + assert(bootstrapBootstrap.componentC is componentC, "Autowiring class with multiple qualifiers failed"); + } + + // Test getting instance from autowired registration will autowire instance + unittest { + auto container = new shared DependencyContainer(); + container.register!ComponentA; + + auto registration = new AutowiredRegistration!ComponentB(typeid(ComponentB), container).singleInstance(); + auto instance = cast(ComponentB) registration.getInstance(new AutowireInstantiationContext()); + + assert(instance.componentA !is null); + } + + // Test autowiring a dynamic array with all qualified types + unittest { + auto container = new shared DependencyContainer(); + container.register!(InterfaceA, ComponentC); + container.register!(InterfaceA, ComponentX); + + auto lord = new LordOfTheComponents(); + container.autowire(lord); + + assert(lord.components.length == 2, "Dynamic array was not autowired"); + } + + // Test autowiring new instance of singleinstance registration with newInstance UDA + unittest { + auto container = new shared DependencyContainer(); + container.register!ComponentA; + + auto regularComponentA = container.resolve!ComponentA; + auto charlie = new ComponentCharlie(); + + container.autowire(charlie); + + assert(charlie.componentA !is regularComponentA, "Autowiring class with AssignNewInstance did not yield a different instance"); + } + + // Test autowiring members from base class + unittest { + auto container = new shared DependencyContainer(); + container.register!ComponentA; + container.register!ComponentB; + container.register!ComponentZ; + + auto instance = new ComponentZ(); + container.autowire(instance); + + assert(instance.componentA !is null); + } + + // Test autowiring optional depenencies + unittest { + auto container = new shared DependencyContainer(); + auto instance = new OuttaTime(); + + container.autowire(instance); + + assert(instance.interfaceA is null); + assert(instance.componentA is null); + assert(instance.componentCs is null); + } +} diff --git a/test/poodinis/containertest.d b/test/poodinis/containertest.d index c4cc1c6..92bfc27 100644 --- a/test/poodinis/containertest.d +++ b/test/poodinis/containertest.d @@ -182,14 +182,14 @@ version(unittest) { // Test register concrete type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto registration = container.register!TestClass; assert(registration.registeredType == typeid(TestClass), "Type of registered type not the same"); } // Test resolve registered type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!TestClass; TestClass actualInstance = container.resolve!TestClass; assert(actualInstance !is null, "Resolved type is null"); @@ -198,7 +198,7 @@ version(unittest) { // Test register interface unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(TestInterface, TestClass); TestInterface actualInstance = container.resolve!TestInterface; assert(actualInstance !is null, "Resolved type is null"); @@ -207,19 +207,19 @@ version(unittest) { // Test resolve non-registered type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); assertThrown!ResolveException(container.resolve!TestClass, "Resolving non-registered type does not fail"); } // Test clear registrations unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!TestClass; container.clearAllRegistrations(); assertThrown!ResolveException(container.resolve!TestClass, "Resolving cleared type does not fail"); } - // Test get singleton of container + // Test get singleton of container (DEPRECATED) unittest { auto instance1 = DependencyContainer.getInstance(); auto instance2 = DependencyContainer.getInstance(); @@ -228,7 +228,7 @@ version(unittest) { // Test resolve single instance for type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!TestClass.singleInstance(); auto instance1 = container.resolve!TestClass; auto instance2 = container.resolve!TestClass; @@ -237,7 +237,7 @@ version(unittest) { // Test resolve new instance for type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!TestClass.newInstance(); auto instance1 = container.resolve!TestClass; auto instance2 = container.resolve!TestClass; @@ -246,7 +246,7 @@ version(unittest) { // Test resolve existing instance for type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto expectedInstance = new TestClass(); container.register!TestClass.existingInstance(expectedInstance); auto actualInstance = container.resolve!TestClass; @@ -255,7 +255,7 @@ version(unittest) { // Test autowire resolved instances unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!AutowiredClass; container.register!ComponentClass; auto componentInstance = container.resolve!ComponentClass; @@ -265,7 +265,7 @@ version(unittest) { // Test circular autowiring unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!ComponentMouse; container.register!ComponentCat; auto mouse = container.resolve!ComponentMouse; @@ -275,7 +275,7 @@ version(unittest) { // Test remove registration unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!TestClass; container.removeRegistration!TestClass; assertThrown!ResolveException(container.resolve!TestClass); @@ -283,7 +283,7 @@ version(unittest) { // Test autowiring does not autowire member where instance is non-null unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto existingA = new AutowiredClass(); auto existingB = new ComponentClass(); existingB.autowiredClass = existingA; @@ -298,7 +298,7 @@ version(unittest) { // Test autowiring circular dependency by third-degree unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Eenie; container.register!Meenie; container.register!Moe; @@ -310,7 +310,7 @@ version(unittest) { // Test autowiring deep circular dependencies unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Ittie; container.register!Bittie; container.register!Banana; @@ -322,7 +322,7 @@ version(unittest) { // Test autowiring deep circular dependencies with newInstance scope does not autowire new instance second time unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Ittie.newInstance(); container.register!Bittie.newInstance(); container.register!Banana.newInstance(); @@ -334,7 +334,7 @@ version(unittest) { // Test autowiring type registered by interface unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Banana; container.register!Bittie; container.register!(SuperInterface, SuperImplementation); @@ -346,7 +346,7 @@ version(unittest) { // Test reusing a container after clearing all registrations unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Banana; container.clearAllRegistrations(); try { @@ -360,14 +360,14 @@ version(unittest) { // Test register multiple concrete classess to same interface type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); } // Test removing all registrations for type with multiple registrations. unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); container.removeRegistration!Color; @@ -375,7 +375,7 @@ version(unittest) { // Test registering same registration again unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto firstRegistration = container.register!(Color, Blue); auto secondRegistration = container.register!(Color, Blue); @@ -384,7 +384,7 @@ version(unittest) { // Test resolve registration with multiple qualifiers unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); try { @@ -397,7 +397,7 @@ version(unittest) { // Test resolve registration with multiple qualifiers using a qualifier unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); auto blueInstance = container.resolve!(Color, Blue); @@ -410,7 +410,7 @@ version(unittest) { // Test autowire of unqualified member typed by interface. unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Spiders; container.register!(TestInterface, TestClass); @@ -421,7 +421,7 @@ version(unittest) { // Register existing registration unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto firstRegistration = container.register!TestClass; auto secondRegistration = container.register!TestClass; @@ -431,7 +431,7 @@ version(unittest) { // Register existing registration by supertype unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto firstRegistration = container.register!(TestInterface, TestClass); auto secondRegistration = container.register!(TestInterface, TestClass); @@ -441,7 +441,7 @@ version(unittest) { // Resolve dependency depending on itself unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Recursive; auto instance = container.resolve!Recursive; @@ -452,7 +452,7 @@ version(unittest) { // Test autowire stack pop-back unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!Moolah; container.register!Wants.newInstance(); container.register!John; @@ -465,7 +465,7 @@ version(unittest) { // Test resolving registration registered in different thread unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto thread = new Thread(delegate() { container.register!TestClass; @@ -478,7 +478,7 @@ version(unittest) { // Test resolving instance previously resolved in different thread unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); shared(TestClass) actualTestClass; container.register!TestClass; @@ -496,7 +496,7 @@ version(unittest) { // Test registering type with option doNotAddConcreteTypeRegistration unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(TestInterface, TestClass)(RegistrationOption.doNotAddConcreteTypeRegistration); auto firstInstance = container.resolve!TestInterface; @@ -505,14 +505,14 @@ version(unittest) { // Test registering conrete type with registration option doNotAddConcreteTypeRegistration does nothing unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!TestClass(RegistrationOption.doNotAddConcreteTypeRegistration); container.resolve!TestClass; } // Test registering type will register by contrete type by default unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(TestInterface, TestClass); auto firstInstance = container.resolve!TestInterface; @@ -523,7 +523,7 @@ version(unittest) { // Test resolving all registrations to an interface unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); @@ -534,7 +534,7 @@ version(unittest) { // Test autowiring instances resolved in array unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!UnrelatedClass; container.register!(TestInterface, TestClassDeux); @@ -546,7 +546,7 @@ version(unittest) { // Test setting up simple dependencies through application context unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.registerContext!TestContext; auto instance = container.resolve!TestClass; @@ -555,7 +555,7 @@ version(unittest) { // Test resolving dependency from registered application context unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.registerContext!TestContext; auto instance = container.resolve!UnrelatedClass; @@ -564,7 +564,7 @@ version(unittest) { // Test autowiring application context unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.register!UnrelatedClass; container.registerContext!AutowiredTestContext; auto instance = container.resolve!ClassWrapper; @@ -575,7 +575,7 @@ version(unittest) { // Test autowiring application context with dependencies registered in same context unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.registerContext!ComplexAutowiredTestContext; auto instance = container.resolve!ClassWrapperWrapper; auto wrapper = container.resolve!ClassWrapper; @@ -588,14 +588,14 @@ version(unittest) { // Test resolving registered context unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.registerContext!TestContext; container.resolve!ApplicationContext; } // Test set persistent registration options unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.setPersistentRegistrationOptions(RegistrationOption.doNotAddConcreteTypeRegistration); container.register!(TestInterface, TestClass); assertThrown!ResolveException(container.resolve!TestClass); @@ -603,7 +603,7 @@ version(unittest) { // Test unset persistent registration options unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.setPersistentRegistrationOptions(RegistrationOption.doNotAddConcreteTypeRegistration); container.unsetPersistentRegistrationOptions(); container.register!(TestInterface, TestClass); @@ -612,21 +612,21 @@ version(unittest) { // Test registration when resolving unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.resolve!(TestInterface, TestClass)(ResolveOption.registerBeforeResolving); container.resolve!TestClass; } // Test set persistent resolve options unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.setPersistentResolveOptions(ResolveOption.registerBeforeResolving); container.resolve!TestClass; } // Test unset persistent resolve options unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); container.setPersistentResolveOptions(ResolveOption.registerBeforeResolving); container.unsetPersistentResolveOptions(); assertThrown!ResolveException(container.resolve!TestClass); @@ -634,20 +634,20 @@ version(unittest) { // Test ResolveOption registerBeforeResolving fails for interfaces unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); assertThrown!ResolveException(container.resolve!TestInterface(ResolveOption.registerBeforeResolving)); } // Test ResolveOption noResolveException does not throw unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto instance = container.resolve!TestInterface(ResolveOption.noResolveException); assert(instance is null); } // ResolveOption noResolveException does not throw for resolveAll unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto instances = container.resolveAll!TestInterface(ResolveOption.noResolveException); assert(instances.length == 0); } diff --git a/test/poodinis/contexttest.d b/test/poodinis/contexttest.d index 9f9bdb9..a65f3c9 100644 --- a/test/poodinis/contexttest.d +++ b/test/poodinis/contexttest.d @@ -87,7 +87,7 @@ version(unittest) { //Test register component registrations from context unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); auto bananaInstance = container.resolve!Banana; @@ -97,7 +97,7 @@ version(unittest) { //Test non-annotated methods are not registered unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); assertThrown!ResolveException(container.resolve!Apple); @@ -105,7 +105,7 @@ version(unittest) { //Test register component by base type unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); auto instance = container.resolve!Fruit; @@ -114,7 +114,7 @@ version(unittest) { //Test register components with multiple candidates unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); @@ -127,7 +127,7 @@ version(unittest) { //Test register component as prototype unittest { - shared(DependencyContainer) container = new DependencyContainer(); + auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container);