Add registering component factories as prototype

Which makes them the opposite of singletons
This commit is contained in:
Mike Bierlee 2015-12-24 21:50:12 +01:00
parent d310640717
commit 4d62f3fdb0
2 changed files with 32 additions and 1 deletions

View file

@ -36,15 +36,25 @@ struct RegisterByType(Type) {
Type type; Type type;
} }
/**
* Components with the prototype registration will be scoped as dependencies which will created
* new instances every time they are resolved. The factory method will be called repeatedly.
*/
struct Prototype {}
public void registerContextComponents(ApplicationContextType : ApplicationContext)(ApplicationContextType context, shared(DependencyContainer) container) { public void registerContextComponents(ApplicationContextType : ApplicationContext)(ApplicationContextType context, shared(DependencyContainer) container) {
foreach (member ; __traits(allMembers, ApplicationContextType)) { foreach (member ; __traits(allMembers, ApplicationContextType)) {
static if (hasUDA!(__traits(getMember, context, member), Component)) { static if (hasUDA!(__traits(getMember, context, member), Component)) {
auto factoryMethod = &__traits(getMember, context, member); auto factoryMethod = &__traits(getMember, context, member);
Registration registration = null; Registration registration = null;
auto createsSingleton = CreatesSingleton.yes;
foreach(attribute; __traits(getAttributes, __traits(getMember, context, member))) { foreach(attribute; __traits(getAttributes, __traits(getMember, context, member))) {
static if (is(attribute == RegisterByType!T, T)) { static if (is(attribute == RegisterByType!T, T)) {
registration = container.register!(typeof(attribute.type), ReturnType!factoryMethod); registration = container.register!(typeof(attribute.type), ReturnType!factoryMethod);
} else static if (__traits(isSame, attribute, Prototype)) {
createsSingleton = CreatesSingleton.no;
} }
} }
@ -52,7 +62,7 @@ public void registerContextComponents(ApplicationContextType : ApplicationContex
registration = container.register!(ReturnType!factoryMethod); registration = container.register!(ReturnType!factoryMethod);
} }
registration.instanceFactory = new InstanceFactory(registration.instanceType, CreatesSingleton.yes, null, factoryMethod); registration.instanceFactory = new InstanceFactory(registration.instanceType, createsSingleton, null, factoryMethod);
} }
} }
} }

View file

@ -47,6 +47,8 @@ version(unittest) {
} }
} }
class PieChart {}
class TestContext : ApplicationContext { class TestContext : ApplicationContext {
@Component @Component
@ -75,6 +77,12 @@ version(unittest) {
public Wolf wolf() { public Wolf wolf() {
return new Wolf(); return new Wolf();
} }
@Component
@Prototype
public PieChart pieChart() {
return new PieChart();
}
} }
//Test register component registrations from context //Test register component registrations from context
@ -117,4 +125,17 @@ version(unittest) {
assert(wolf.getYell() == "Wooooooooooo"); assert(wolf.getYell() == "Wooooooooooo");
} }
//Test register component as prototype
unittest {
shared(DependencyContainer) container = new DependencyContainer();
auto context = new TestContext();
context.registerContextComponents(container);
auto firstInstance = container.resolve!PieChart;
auto secondInstance = container.resolve!PieChart;
assert(firstInstance !is null && secondInstance !is null);
assert(firstInstance !is secondInstance);
}
} }