Split autowire code up into multiple functions

This commit is contained in:
Mike Bierlee 2016-12-06 23:00:30 +01:00
parent 2c62f8dbef
commit f1bd2260d1

View file

@ -27,7 +27,7 @@ import std.string;
import std.traits; import std.traits;
import std.range; import std.range;
struct UseMemberType {}; private struct UseMemberType {};
/** /**
* UDA for annotating class members as candidates for autowiring. * UDA for annotating class members as candidates for autowiring.
@ -62,11 +62,10 @@ struct UseMemberType {};
* autowire member "fuelEngine" as if it's of type "FuelEngine". This means that the members of instance "fuelEngine" * autowire member "fuelEngine" as if it's of type "FuelEngine". This means that the members of instance "fuelEngine"
* will also be autowired because the autowire mechanism knows that member "fuelEngine" is an instance of "FuelEngine" * will also be autowired because the autowire mechanism knows that member "fuelEngine" is an instance of "FuelEngine"
*/ */
struct Autowire(QualifierType = UseMemberType) { struct Autowire(QualifierType) {
QualifierType qualifier; QualifierType qualifier;
}; };
/** /**
* UDA for marking autowired dependencies optional. * UDA for marking autowired dependencies optional.
* Optional dependencies will not lead to a resolveException when there is no type registered for them. * Optional dependencies will not lead to a resolveException when there is no type registered for them.
@ -130,32 +129,51 @@ private void printDebugAutowiringArray(TypeInfo superTypeInfo, TypeInfo instance
} }
private void autowireMember(string member, size_t memberIndex, Type)(shared(DependencyContainer) container, Type instance) { private void autowireMember(string member, size_t memberIndex, Type)(shared(DependencyContainer) container, Type instance) {
foreach(autowireAttribute; __traits(getAttributes, Type.tupleof[memberIndex])) { foreach(attribute; __traits(getAttributes, Type.tupleof[memberIndex])) {
static if (__traits(isSame, autowireAttribute, Autowire) || is(autowireAttribute == Autowire!T, T)) { static if (is(attribute == Autowire!T, T)) {
injectInstance!(member, memberIndex, attribute)(container, instance);
} else if (__traits(isSame, attribute, Autowire)) {
injectInstance!(member, memberIndex, Autowire!UseMemberType)(container, instance);
}
}
}
private void injectInstance(string member, size_t memberIndex, autowireAttribute, Type)(shared(DependencyContainer) container, Type instance) {
if (instance.tupleof[memberIndex] is null) { if (instance.tupleof[memberIndex] is null) {
alias MemberType = typeof(Type.tupleof[memberIndex]); alias MemberType = typeof(Type.tupleof[memberIndex]);
enum assignNewInstance = hasUDA!(Type.tupleof[memberIndex], AssignNewInstance);
enum isOptional = hasUDA!(Type.tupleof[memberIndex], OptionalDependency); enum isOptional = hasUDA!(Type.tupleof[memberIndex], OptionalDependency);
static if (isDynamicArray!MemberType) { static if (isDynamicArray!MemberType) {
injectMultipleInstances!(member, memberIndex, isOptional, MemberType)(container, instance);
} else {
injectSingleInstance!(member, memberIndex, autowireAttribute, isOptional, MemberType)(container, instance);
}
}
}
private void injectMultipleInstances(string member, size_t memberIndex, bool isOptional, MemberType, Type)(shared(DependencyContainer) container, Type instance) {
alias MemberElementType = ElementType!MemberType; alias MemberElementType = ElementType!MemberType;
static if (isOptional) { static if (isOptional) {
auto instances = container.resolveAll!MemberElementType(ResolveOption.noResolveException); auto instances = container.resolveAll!MemberElementType(ResolveOption.noResolveException);
} else { } else {
auto instances = container.resolveAll!MemberElementType; auto instances = container.resolveAll!MemberElementType;
} }
instance.tupleof[memberIndex] = instances; instance.tupleof[memberIndex] = instances;
debug(poodinisVerbose) { debug(poodinisVerbose) {
printDebugAutowiringArray(typeid(MemberElementType), typeid(Type), &instance, member); printDebugAutowiringArray(typeid(MemberElementType), typeid(Type), &instance, member);
} }
} else { }
private void injectSingleInstance(string member, size_t memberIndex, autowireAttribute, bool isOptional, MemberType, Type)(shared(DependencyContainer) container, Type instance) {
debug(poodinisVerbose) { debug(poodinisVerbose) {
TypeInfo qualifiedInstanceType = typeid(MemberType); TypeInfo qualifiedInstanceType = typeid(MemberType);
} }
enum assignNewInstance = hasUDA!(Type.tupleof[memberIndex], AssignNewInstance);
MemberType qualifiedInstance; MemberType qualifiedInstance;
static if (is(autowireAttribute == Autowire!T, T) && !is(autowireAttribute.qualifier == UseMemberType)) { static if (is(autowireAttribute == Autowire!T, T) && !is(typeof(autowireAttribute.qualifier) == UseMemberType)) {
alias QualifierType = typeof(autowireAttribute.qualifier); alias QualifierType = typeof(autowireAttribute.qualifier);
qualifiedInstance = createOrResolveInstance!(MemberType, QualifierType, assignNewInstance, isOptional)(container); qualifiedInstance = createOrResolveInstance!(MemberType, QualifierType, assignNewInstance, isOptional)(container);
debug(poodinisVerbose) { debug(poodinisVerbose) {
@ -170,12 +188,6 @@ private void autowireMember(string member, size_t memberIndex, Type)(shared(Depe
debug(poodinisVerbose) { debug(poodinisVerbose) {
printDebugAutowiringCandidate(qualifiedInstanceType, &qualifiedInstance, typeid(Type), &instance, member); printDebugAutowiringCandidate(qualifiedInstanceType, &qualifiedInstance, typeid(Type), &instance, member);
} }
}
}
break;
}
}
} }
private QualifierType createOrResolveInstance(MemberType, QualifierType, bool createNew, bool isOptional)(shared(DependencyContainer) container) { private QualifierType createOrResolveInstance(MemberType, QualifierType, bool createNew, bool isOptional)(shared(DependencyContainer) container) {