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 {}
|
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) {
|
public void registerContextComponents(ApplicationContextType : ApplicationContext)(ApplicationContextType context, shared(DependencyContainer) container) {
|
||||||
import std.stdio;
|
|
||||||
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);
|
||||||
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);
|
registration.instanceFactory = new InstanceFactory(registration.instanceType, CreatesSingleton.yes, null, factoryMethod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,14 @@ import std.exception;
|
||||||
|
|
||||||
version(unittest) {
|
version(unittest) {
|
||||||
|
|
||||||
|
interface Fruit {
|
||||||
|
string getShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Animal {
|
||||||
|
string getYell();
|
||||||
|
}
|
||||||
|
|
||||||
class Banana {
|
class Banana {
|
||||||
public string color;
|
public string color;
|
||||||
|
|
||||||
|
@ -21,6 +29,24 @@ version(unittest) {
|
||||||
|
|
||||||
class Apple {}
|
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 {
|
class TestContext : ApplicationContext {
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@ -31,6 +57,24 @@ version(unittest) {
|
||||||
public Apple apple() {
|
public Apple apple() {
|
||||||
return new 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
|
//Test register component registrations from context
|
||||||
|
@ -51,4 +95,26 @@ version(unittest) {
|
||||||
assertThrown!ResolveException(container.resolve!Apple);
|
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