Fix autowiring classes with non-symbolic unassignable members (such as aliases)

This commit is contained in:
Mike Bierlee 2014-07-09 23:15:05 +02:00
parent af8e154dc5
commit b38bccc03c
2 changed files with 148 additions and 122 deletions

View file

@ -20,19 +20,21 @@ class Autowire{};
public void autowire(Type)(Container container, Type instance) { public void autowire(Type)(Container container, Type instance) {
foreach (member ; __traits(allMembers, Type)) { foreach (member ; __traits(allMembers, Type)) {
foreach (attribute; mixin(`__traits(getAttributes, Type.` ~ member ~ `)`) ) { static if(__traits(compiles, __traits( getMember, Type, member )) && __traits(compiles, __traits(getAttributes, __traits(getMember, Type, member )))) {
if (is(attribute : Autowire) && __traits(getMember, instance, member) is null){ foreach(attribute; __traits(getAttributes, __traits(getMember, Type, member))) {
alias TypeTuple!(__traits(getMember, instance, member)) memberReference; if (is(attribute : Autowire) && __traits(getMember, instance, member) is null){
auto autowirableInstance = container.resolve!(typeof(memberReference)); alias TypeTuple!(__traits(getMember, instance, member)) memberReference;
debug { auto autowirableInstance = container.resolve!(typeof(memberReference));
auto autowirableType = typeid(typeof(memberReference[0])); debug {
auto autowireableAddress = &autowirableInstance; auto autowirableType = typeid(typeof(memberReference[0]));
auto memberType = typeid(Type); auto autowireableAddress = &autowirableInstance;
auto instanceAddress = &instance; auto memberType = typeid(Type);
writeln(format("DEBUG: Autowire instance [%s@%s] to [%s@%s].%s", autowirableType, autowireableAddress, memberType, instanceAddress, member)); auto instanceAddress = &instance;
} writeln(format("DEBUG: Autowire instance [%s@%s] to [%s@%s].%s", autowirableType, autowireableAddress, memberType, instanceAddress, member));
}
__traits(getMember, instance, member) = autowirableInstance; __traits(getMember, instance, member) = autowirableInstance;
}
} }
} }
} }

View file

@ -49,6 +49,19 @@ version(unittest) {
mixin AutowireConstructor; mixin AutowireConstructor;
} }
class ComponentDeclarationCocktail {
alias noomer = int;
@Autowire
public ComponentA componentA;
public void doesNothing() {
}
~this(){
}
}
// Test autowiring concrete type to existing instance // Test autowiring concrete type to existing instance
unittest { unittest {
auto container = new Container(); auto container = new Container();
@ -108,4 +121,15 @@ version(unittest) {
container.clearAllRegistrations(); container.clearAllRegistrations();
} }
// Test autowire class with alias declaration
unittest {
auto container = new Container();
container.register!ComponentA;
auto componentDeclarationCocktail = new ComponentDeclarationCocktail();
container.autowire(componentDeclarationCocktail);
assert(componentDeclarationCocktail.componentA !is null, "Autowiring class with non-assignable declarations failed");
}
} }