Add registration of components through factory methods

A basic version of Bean factories from the Spring framework
This commit is contained in:
Mike Bierlee 2015-12-24 18:45:18 +01:00
parent c4bfe02392
commit 1bf1734c53
2 changed files with 63 additions and 1 deletions

View file

@ -14,7 +14,27 @@
module poodinis.context;
import poodinis.container;
import poodinis.registration;
import std.traits;
class ApplicationContext {
public void registerDependencies(shared(DependencyContainer) container) {}
}
/**
* A component annotation is used for specifying which factory methods produce components in
* an application context.
*/
struct Component {}
public void registerContextComponents(ApplicationContextType : ApplicationContext)(ApplicationContextType context, shared(DependencyContainer) container) {
import std.stdio;
foreach (member ; __traits(allMembers, ApplicationContextType)) {
static if (hasUDA!(__traits(getMember, context, member), Component)) {
auto factoryMethod = &__traits(getMember, context, member);
auto registration = container.register!(ReturnType!factoryMethod);
registration.instanceFactory = new InstanceFactory(registration.instantiatableType, CreatesSingleton.yes, null, factoryMethod);
}
}
}

View file

@ -5,8 +5,50 @@
* The full terms of the license can be found in the LICENSE file.
*/
import poodinis.context;
import poodinis;
import std.exception;
version(unittest) {
class Banana {
public string color;
this(string color) {
this.color = color;
}
}
class Apple {}
class TestContext : ApplicationContext {
@Component
public Banana banana() {
return new Banana("Yellow");
}
public Apple apple() {
return new Apple();
}
}
//Test register component registrations from context
unittest {
shared(DependencyContainer) container = new DependencyContainer();
auto context = new TestContext();
context.registerContextComponents(container);
auto bananaInstance = container.resolve!Banana;
assert(bananaInstance.color == "Yellow");
}
//Test non-annotated methods are not registered
unittest {
shared(DependencyContainer) container = new DependencyContainer();
auto context = new TestContext();
context.registerContextComponents(container);
assertThrown!ResolveException(container.resolve!Apple);
}
}