mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Move factory stuff to own module
This commit is contained in:
parent
ccdef46dde
commit
44e77aff9c
|
@ -19,6 +19,7 @@ module poodinis.autowire;
|
|||
|
||||
import poodinis.container;
|
||||
import poodinis.registration;
|
||||
import poodinis.factory;
|
||||
|
||||
import std.exception;
|
||||
import std.stdio;
|
||||
|
|
|
@ -15,6 +15,7 @@ module poodinis.context;
|
|||
|
||||
import poodinis.container;
|
||||
import poodinis.registration;
|
||||
import poodinis.factory;
|
||||
|
||||
import std.traits;
|
||||
|
||||
|
|
65
source/poodinis/factory.d
Normal file
65
source/poodinis/factory.d
Normal file
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* This module contains instance factory facilities
|
||||
*
|
||||
* Authors:
|
||||
* Mike Bierlee, m.bierlee@lostmoment.com
|
||||
* Copyright: 2014-2016 Mike Bierlee
|
||||
* License:
|
||||
* This software is licensed under the terms of the MIT license.
|
||||
* The full terms of the license can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
module poodinis.factory;
|
||||
|
||||
import std.typecons;
|
||||
import std.exception;
|
||||
|
||||
debug {
|
||||
import std.string;
|
||||
import std.stdio;
|
||||
}
|
||||
|
||||
alias CreatesSingleton = Flag!"CreatesSingleton";
|
||||
alias InstanceFactoryMethod = Object delegate();
|
||||
|
||||
class InstanceCreationException : Exception {
|
||||
this(string message, string file = __FILE__, size_t line = __LINE__) {
|
||||
super(message, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
class InstanceFactory {
|
||||
private TypeInfo_Class instanceType = null;
|
||||
private Object instance = null;
|
||||
private CreatesSingleton createsSingleton;
|
||||
private InstanceFactoryMethod factoryMethod;
|
||||
|
||||
this(TypeInfo_Class instanceType, CreatesSingleton createsSingleton = CreatesSingleton.yes, Object existingInstance = null, InstanceFactoryMethod factoryMethod = null) {
|
||||
this.instanceType = instanceType;
|
||||
this.createsSingleton = existingInstance !is null ? CreatesSingleton.yes : createsSingleton;
|
||||
this.instance = existingInstance;
|
||||
this.factoryMethod = factoryMethod !is null ? factoryMethod : &this.createInstance;
|
||||
}
|
||||
|
||||
public Object getInstance() {
|
||||
if (createsSingleton && instance !is null) {
|
||||
debug(poodinisVerbose) {
|
||||
writeln(format("DEBUG: Existing instance returned of type %s", instanceType.toString()));
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
debug(poodinisVerbose) {
|
||||
writeln(format("DEBUG: Creating new instance of type %s", instanceType.toString()));
|
||||
}
|
||||
|
||||
instance = factoryMethod();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Object createInstance() {
|
||||
enforce!InstanceCreationException(instanceType, "Instance type is not defined, cannot create instance without knowing its type.");
|
||||
return instanceType.create();
|
||||
}
|
||||
}
|
|
@ -15,3 +15,4 @@ public import poodinis.autowire;
|
|||
public import poodinis.container;
|
||||
public import poodinis.registration;
|
||||
public import poodinis.context;
|
||||
public import poodinis.factory;
|
||||
|
|
|
@ -14,20 +14,7 @@
|
|||
module poodinis.registration;
|
||||
|
||||
import poodinis.container;
|
||||
|
||||
import std.typecons;
|
||||
import std.exception;
|
||||
|
||||
debug {
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
}
|
||||
|
||||
class InstanceCreationException : Exception {
|
||||
this(string message, string file = __FILE__, size_t line = __LINE__) {
|
||||
super(message, file, line);
|
||||
}
|
||||
}
|
||||
import poodinis.factory;
|
||||
|
||||
class Registration {
|
||||
private TypeInfo _registeredType = null;
|
||||
|
@ -74,45 +61,6 @@ class Registration {
|
|||
}
|
||||
}
|
||||
|
||||
alias CreatesSingleton = Flag!"CreatesSingleton";
|
||||
alias InstanceFactoryMethod = Object delegate();
|
||||
|
||||
class InstanceFactory {
|
||||
private TypeInfo_Class instanceType = null;
|
||||
private Object instance = null;
|
||||
private CreatesSingleton createsSingleton;
|
||||
private InstanceFactoryMethod factoryMethod;
|
||||
|
||||
this(TypeInfo_Class instanceType, CreatesSingleton createsSingleton = CreatesSingleton.yes, Object existingInstance = null, InstanceFactoryMethod factoryMethod = null) {
|
||||
this.instanceType = instanceType;
|
||||
this.createsSingleton = existingInstance !is null ? CreatesSingleton.yes : createsSingleton;
|
||||
this.instance = existingInstance;
|
||||
this.factoryMethod = factoryMethod !is null ? factoryMethod : &this.createInstance;
|
||||
}
|
||||
|
||||
public Object getInstance() {
|
||||
if (createsSingleton && instance !is null) {
|
||||
debug(poodinisVerbose) {
|
||||
writeln(format("DEBUG: Existing instance returned of type %s", instanceType.toString()));
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
debug(poodinisVerbose) {
|
||||
writeln(format("DEBUG: Creating new instance of type %s", instanceType.toString()));
|
||||
}
|
||||
|
||||
instance = factoryMethod();
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Object createInstance() {
|
||||
enforce!InstanceCreationException(instanceType, "Instance type is not defined, cannot create instance without knowing its type.");
|
||||
return instanceType.create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scopes registrations to return the same instance every time a given registration is resolved.
|
||||
*
|
||||
|
|
72
test/poodinis/factorytest.d
Normal file
72
test/poodinis/factorytest.d
Normal file
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
version(unittest) {
|
||||
|
||||
interface TestInterface {}
|
||||
|
||||
class TestImplementation : TestInterface {
|
||||
public string someContent = "";
|
||||
}
|
||||
|
||||
// Test instance factory with singletons
|
||||
unittest {
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.yes, null);
|
||||
auto instanceOne = factory.getInstance();
|
||||
auto instanceTwo = factory.getInstance();
|
||||
|
||||
assert(instanceOne !is null, "Created factory instance is null");
|
||||
assert(instanceOne is instanceTwo, "Created factory instance is not the same");
|
||||
}
|
||||
|
||||
// Test instance factory with new instances
|
||||
unittest {
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.no, null);
|
||||
auto instanceOne = factory.getInstance();
|
||||
auto instanceTwo = factory.getInstance();
|
||||
|
||||
assert(instanceOne !is null, "Created factory instance is null");
|
||||
assert(instanceOne !is instanceTwo, "Created factory instance is the same");
|
||||
}
|
||||
|
||||
// Test instance factory with existing instances
|
||||
unittest {
|
||||
auto existingInstance = new TestImplementation();
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.yes, existingInstance);
|
||||
auto instanceOne = factory.getInstance();
|
||||
auto instanceTwo = factory.getInstance();
|
||||
|
||||
assert(instanceOne is existingInstance, "Created factory instance is not the existing instance");
|
||||
assert(instanceTwo is existingInstance, "Created factory instance is not the existing instance when called again");
|
||||
}
|
||||
|
||||
// Test instance factory with existing instances when setting singleton flag to "no"
|
||||
unittest {
|
||||
auto existingInstance = new TestImplementation();
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.no, existingInstance);
|
||||
auto instance = factory.getInstance();
|
||||
|
||||
assert(instance is existingInstance, "Created factory instance is not the existing instance");
|
||||
}
|
||||
|
||||
// Test creating instance using custom factory method
|
||||
unittest {
|
||||
Object factoryMethod() {
|
||||
auto instance = new TestImplementation();
|
||||
instance.someContent = "Ducks!";
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto factory = new InstanceFactory(null, CreatesSingleton.yes, null, &factoryMethod);
|
||||
auto instance = cast(TestImplementation) factory.getInstance();
|
||||
|
||||
assert(instance !is null, "No instance was created by factory or could not be cast to expected type");
|
||||
assert(instance.someContent == "Ducks!");
|
||||
}
|
||||
}
|
|
@ -65,59 +65,4 @@ version(unittest) {
|
|||
assert(firstInstance is secondInstance);
|
||||
}
|
||||
|
||||
// Test instance factory with singletons
|
||||
unittest {
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.yes, null);
|
||||
auto instanceOne = factory.getInstance();
|
||||
auto instanceTwo = factory.getInstance();
|
||||
|
||||
assert(instanceOne !is null, "Created factory instance is null");
|
||||
assert(instanceOne is instanceTwo, "Created factory instance is not the same");
|
||||
}
|
||||
|
||||
// Test instance factory with new instances
|
||||
unittest {
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.no, null);
|
||||
auto instanceOne = factory.getInstance();
|
||||
auto instanceTwo = factory.getInstance();
|
||||
|
||||
assert(instanceOne !is null, "Created factory instance is null");
|
||||
assert(instanceOne !is instanceTwo, "Created factory instance is the same");
|
||||
}
|
||||
|
||||
// Test instance factory with existing instances
|
||||
unittest {
|
||||
auto existingInstance = new TestImplementation();
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.yes, existingInstance);
|
||||
auto instanceOne = factory.getInstance();
|
||||
auto instanceTwo = factory.getInstance();
|
||||
|
||||
assert(instanceOne is existingInstance, "Created factory instance is not the existing instance");
|
||||
assert(instanceTwo is existingInstance, "Created factory instance is not the existing instance when called again");
|
||||
}
|
||||
|
||||
// Test instance factory with existing instances when setting singleton flag to "no"
|
||||
unittest {
|
||||
auto existingInstance = new TestImplementation();
|
||||
auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.no, existingInstance);
|
||||
auto instance = factory.getInstance();
|
||||
|
||||
assert(instance is existingInstance, "Created factory instance is not the existing instance");
|
||||
}
|
||||
|
||||
// Test creating instance using custom factory method
|
||||
unittest {
|
||||
Object factoryMethod() {
|
||||
auto instance = new TestImplementation();
|
||||
instance.someContent = "Ducks!";
|
||||
return instance;
|
||||
}
|
||||
|
||||
auto factory = new InstanceFactory(null, CreatesSingleton.yes, null, &factoryMethod);
|
||||
auto instance = cast(TestImplementation) factory.getInstance();
|
||||
|
||||
assert(instance !is null, "No instance was created by factory or could not be cast to expected type");
|
||||
assert(instance.someContent == "Ducks!");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue