mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Add specifying components by supertype
This commit is contained in:
parent
d888d0a808
commit
57b548aeae
|
@ -28,12 +28,30 @@ class ApplicationContext {
|
|||
*/
|
||||
struct Component {}
|
||||
|
||||
/**
|
||||
* This annotation allows you to specify by which super type the component should be registered. This
|
||||
* enables you to use type-qualified alternatives for dependencies.
|
||||
*/
|
||||
struct RegisterByType(Type) {
|
||||
Type type;
|
||||
}
|
||||
|
||||
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 registration = null;
|
||||
|
||||
foreach(attribute; __traits(getAttributes, __traits(getMember, context, member))) {
|
||||
static if (is(attribute == RegisterByType!T, T)) {
|
||||
registration = container.register!(typeof(attribute.type), ReturnType!factoryMethod);
|
||||
}
|
||||
}
|
||||
|
||||
if (registration is null) {
|
||||
registration = container.register!(ReturnType!factoryMethod);
|
||||
}
|
||||
|
||||
registration.instanceFactory = new InstanceFactory(registration.instanceType, CreatesSingleton.yes, null, factoryMethod);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,14 @@ import std.exception;
|
|||
|
||||
version(unittest) {
|
||||
|
||||
interface Fruit {
|
||||
string getShape();
|
||||
}
|
||||
|
||||
interface Animal {
|
||||
string getYell();
|
||||
}
|
||||
|
||||
class Banana {
|
||||
public string color;
|
||||
|
||||
|
@ -21,6 +29,24 @@ version(unittest) {
|
|||
|
||||
class Apple {}
|
||||
|
||||
class Pear : Fruit {
|
||||
public override string getShape() {
|
||||
return "Pear shaped";
|
||||
}
|
||||
}
|
||||
|
||||
class Rabbit : Animal {
|
||||
public override string getYell() {
|
||||
return "Squeeeeeel";
|
||||
}
|
||||
}
|
||||
|
||||
class Wolf : Animal {
|
||||
public override string getYell() {
|
||||
return "Wooooooooooo";
|
||||
}
|
||||
}
|
||||
|
||||
class TestContext : ApplicationContext {
|
||||
|
||||
@Component
|
||||
|
@ -31,6 +57,24 @@ version(unittest) {
|
|||
public Apple apple() {
|
||||
return new Apple();
|
||||
}
|
||||
|
||||
@Component
|
||||
@RegisterByType!Fruit
|
||||
public Pear pear() {
|
||||
return new Pear();
|
||||
}
|
||||
|
||||
@Component
|
||||
@RegisterByType!Animal
|
||||
public Rabbit rabbit() {
|
||||
return new Rabbit();
|
||||
}
|
||||
|
||||
@Component
|
||||
@RegisterByType!Animal
|
||||
public Wolf wolf() {
|
||||
return new Wolf();
|
||||
}
|
||||
}
|
||||
|
||||
//Test register component registrations from context
|
||||
|
@ -51,4 +95,26 @@ version(unittest) {
|
|||
assertThrown!ResolveException(container.resolve!Apple);
|
||||
}
|
||||
|
||||
//Test register component by base type
|
||||
unittest {
|
||||
shared(DependencyContainer) container = new DependencyContainer();
|
||||
auto context = new TestContext();
|
||||
context.registerContextComponents(container);
|
||||
auto instance = container.resolve!Fruit;
|
||||
assert(instance.getShape() == "Pear shaped");
|
||||
}
|
||||
|
||||
//Test register components with multiple candidates
|
||||
unittest {
|
||||
shared(DependencyContainer) container = new DependencyContainer();
|
||||
auto context = new TestContext();
|
||||
context.registerContextComponents(container);
|
||||
|
||||
auto rabbit = container.resolve!(Animal, Rabbit);
|
||||
assert(rabbit.getYell() == "Squeeeeeel");
|
||||
|
||||
auto wolf = container.resolve!(Animal, Wolf);
|
||||
assert(wolf.getYell() == "Wooooooooooo");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue