mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
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.
This commit is contained in:
parent
02dbe20c64
commit
9e5a27d046
|
@ -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)
|
||||
|
|
|
@ -35,7 +35,7 @@ class DataWriter {
|
|||
}
|
||||
|
||||
void main() {
|
||||
auto dependencies = DependencyContainer.getInstance();
|
||||
auto dependencies = new shared DependencyContainer();
|
||||
dependencies.register!DataWriter;
|
||||
dependencies.register!(Database, RelationalDatabase);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -44,7 +44,7 @@ class HybridCar {
|
|||
}
|
||||
|
||||
void main() {
|
||||
auto dependencies = DependencyContainer.getInstance();
|
||||
auto dependencies = new shared DependencyContainer();
|
||||
|
||||
dependencies.register!HybridCar;
|
||||
dependencies.register!(Engine, FuelEngine);
|
||||
|
|
|
@ -16,7 +16,7 @@ class DataWriter {
|
|||
}
|
||||
|
||||
void main() {
|
||||
auto dependencies = DependencyContainer.getInstance();
|
||||
auto dependencies = new shared DependencyContainer();
|
||||
dependencies.register!DataWriter;
|
||||
dependencies.register!(Database, RelationalDatabase);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue