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.container;
|
||||||
import poodinis.registration;
|
import poodinis.registration;
|
||||||
|
import poodinis.factory;
|
||||||
|
|
||||||
import std.exception;
|
import std.exception;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
|
|
|
@ -15,6 +15,7 @@ module poodinis.context;
|
||||||
|
|
||||||
import poodinis.container;
|
import poodinis.container;
|
||||||
import poodinis.registration;
|
import poodinis.registration;
|
||||||
|
import poodinis.factory;
|
||||||
|
|
||||||
import std.traits;
|
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.container;
|
||||||
public import poodinis.registration;
|
public import poodinis.registration;
|
||||||
public import poodinis.context;
|
public import poodinis.context;
|
||||||
|
public import poodinis.factory;
|
||||||
|
|
|
@ -14,20 +14,7 @@
|
||||||
module poodinis.registration;
|
module poodinis.registration;
|
||||||
|
|
||||||
import poodinis.container;
|
import poodinis.container;
|
||||||
|
import poodinis.factory;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Registration {
|
class Registration {
|
||||||
private TypeInfo _registeredType = null;
|
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.
|
* 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);
|
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