diff --git a/source/poodinis/context.d b/source/poodinis/context.d index bd4fb65..1b5aecb 100644 --- a/source/poodinis/context.d +++ b/source/poodinis/context.d @@ -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); + } + } +} diff --git a/test/poodinis/contexttest.d b/test/poodinis/contexttest.d index fd142d1..850c6bb 100644 --- a/test/poodinis/contexttest.d +++ b/test/poodinis/contexttest.d @@ -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); + } + }