Add autowiring of dynamic arrays

This commit is contained in:
Mike Bierlee 2015-07-04 14:05:53 +02:00
parent 805a3ebaeb
commit 1ce37e6eda
3 changed files with 46 additions and 14 deletions

View file

@ -3,6 +3,7 @@ Poodinis Changelog
**Next Release**
* ADD canonical package module "package.d". Use "import poodinis;" to import the project.
* DEPRECATE module "dependency.d". Please use the canonical package module. See previous point.
* ADD autowiring of dynamic arrays. All registered instances of the element type of the array will be assigned to it.
**Version 2.1.0**
* ADD option for registering a class by concrete type when registering that class by supertype.

View file

@ -22,6 +22,7 @@ public import poodinis.container;
import std.exception;
import std.stdio;
import std.string;
import std.traits;
struct UseMemberType {};
@ -92,6 +93,10 @@ private void printDebugAutowiringCandidate(TypeInfo candidateInstanceType, void*
writeln(format("DEBUG: Autowired instance [%s@%s] to [%s@%s].%s", candidateInstanceType, candidateInstanceAddress, instanceType, instanceAddress, member));
}
private void printDebugAutowiringArray(TypeInfo superTypeInfo, TypeInfo instanceType, void* instanceAddress, string member) {
writeln(format("DEBUG: Autowired all registered instances of super type %s to [%s@%s].%s", superTypeInfo, instanceType, instanceAddress, member));
}
private void autowireMember(string member, Type)(shared(DependencyContainer) container, Type instance) {
static if(__traits(compiles, __traits(getMember, instance, member)) && __traits(compiles, __traits(getAttributes, __traits(getMember, instance, member)))) {
foreach(autowireAttribute; __traits(getAttributes, __traits(getMember, instance, member))) {
@ -99,25 +104,34 @@ private void autowireMember(string member, Type)(shared(DependencyContainer) con
if (__traits(getMember, instance, member) is null) {
alias MemberType = typeof(__traits(getMember, instance, member));
debug(poodinisVerbose) {
TypeInfo qualifiedInstanceType = typeid(MemberType);
}
MemberType qualifiedInstance;
static if (is(autowireAttribute == Autowire!T, T) && !is(autowireAttribute.qualifier == UseMemberType)) {
alias QualifierType = typeof(autowireAttribute.qualifier);
qualifiedInstance = container.resolve!(MemberType, QualifierType);
static if (isDynamicArray!MemberType) {
alias ElementType = typeof(__traits(getMember, instance, member)[0]);
auto instances = container.resolveAll!ElementType;
__traits(getMember, instance, member) = instances;
debug(poodinisVerbose) {
qualifiedInstanceType = typeid(QualifierType);
printDebugAutowiringArray(typeid(ElementType), typeid(Type), &instance, member);
}
} else {
qualifiedInstance = container.resolve!(MemberType);
}
debug(poodinisVerbose) {
TypeInfo qualifiedInstanceType = typeid(MemberType);
}
__traits(getMember, instance, member) = qualifiedInstance;
MemberType qualifiedInstance;
static if (is(autowireAttribute == Autowire!T, T) && !is(autowireAttribute.qualifier == UseMemberType)) {
alias QualifierType = typeof(autowireAttribute.qualifier);
qualifiedInstance = container.resolve!(MemberType, QualifierType);
debug(poodinisVerbose) {
qualifiedInstanceType = typeid(QualifierType);
}
} else {
qualifiedInstance = container.resolve!(MemberType);
}
debug(poodinisVerbose) {
printDebugAutowiringCandidate(qualifiedInstanceType, &qualifiedInstance, typeid(Type), &instance, member);
__traits(getMember, instance, member) = qualifiedInstance;
debug(poodinisVerbose) {
printDebugAutowiringCandidate(qualifiedInstanceType, &qualifiedInstance, typeid(Type), &instance, member);
}
}
}

View file

@ -59,6 +59,11 @@ version(unittest) {
public InterfaceA componentC;
}
class LordOfTheComponents {
@Autowire
public InterfaceA[] components;
}
// Test autowiring concrete type to existing instance
unittest {
shared(DependencyContainer) container = new DependencyContainer();
@ -153,4 +158,16 @@ version(unittest) {
assert(instance.componentA !is null);
}
// Test autowiring a dynamic array with all qualified types
unittest {
shared(DependencyContainer) container = new DependencyContainer();
container.register!(InterfaceA, ComponentC);
container.register!(InterfaceA, ComponentX);
auto lord = new LordOfTheComponents();
container.autowire(lord);
assert(lord.components.length == 2, "Dynamic array was not autowired");
}
}