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,54 +129,67 @@ 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)) {
if (instance.tupleof[memberIndex] is null) { injectInstance!(member, memberIndex, attribute)(container, instance);
alias MemberType = typeof(Type.tupleof[memberIndex]); } else if (__traits(isSame, attribute, Autowire)) {
injectInstance!(member, memberIndex, Autowire!UseMemberType)(container, instance);
enum assignNewInstance = hasUDA!(Type.tupleof[memberIndex], AssignNewInstance);
enum isOptional = hasUDA!(Type.tupleof[memberIndex], OptionalDependency);
static if (isDynamicArray!MemberType) {
alias MemberElementType = ElementType!MemberType;
static if (isOptional) {
auto instances = container.resolveAll!MemberElementType(ResolveOption.noResolveException);
} else {
auto instances = container.resolveAll!MemberElementType;
}
instance.tupleof[memberIndex] = instances;
debug(poodinisVerbose) {
printDebugAutowiringArray(typeid(MemberElementType), typeid(Type), &instance, member);
}
} else {
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 = createOrResolveInstance!(MemberType, QualifierType, assignNewInstance, isOptional)(container);
debug(poodinisVerbose) {
qualifiedInstanceType = typeid(QualifierType);
}
} else {
qualifiedInstance = createOrResolveInstance!(MemberType, MemberType, assignNewInstance, isOptional)(container);
}
instance.tupleof[memberIndex] = qualifiedInstance;
debug(poodinisVerbose) {
printDebugAutowiringCandidate(qualifiedInstanceType, &qualifiedInstance, typeid(Type), &instance, member);
}
}
}
break;
} }
} }
} }
private void injectInstance(string member, size_t memberIndex, autowireAttribute, Type)(shared(DependencyContainer) container, Type instance) {
if (instance.tupleof[memberIndex] is null) {
alias MemberType = typeof(Type.tupleof[memberIndex]);
enum isOptional = hasUDA!(Type.tupleof[memberIndex], OptionalDependency);
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;
static if (isOptional) {
auto instances = container.resolveAll!MemberElementType(ResolveOption.noResolveException);
} else {
auto instances = container.resolveAll!MemberElementType;
}
instance.tupleof[memberIndex] = instances;
debug(poodinisVerbose) {
printDebugAutowiringArray(typeid(MemberElementType), typeid(Type), &instance, member);
}
}
private void injectSingleInstance(string member, size_t memberIndex, autowireAttribute, bool isOptional, MemberType, Type)(shared(DependencyContainer) container, Type instance) {
debug(poodinisVerbose) {
TypeInfo qualifiedInstanceType = typeid(MemberType);
}
enum assignNewInstance = hasUDA!(Type.tupleof[memberIndex], AssignNewInstance);
MemberType qualifiedInstance;
static if (is(autowireAttribute == Autowire!T, T) && !is(typeof(autowireAttribute.qualifier) == UseMemberType)) {
alias QualifierType = typeof(autowireAttribute.qualifier);
qualifiedInstance = createOrResolveInstance!(MemberType, QualifierType, assignNewInstance, isOptional)(container);
debug(poodinisVerbose) {
qualifiedInstanceType = typeid(QualifierType);
}
} else {
qualifiedInstance = createOrResolveInstance!(MemberType, MemberType, assignNewInstance, isOptional)(container);
}
instance.tupleof[memberIndex] = qualifiedInstance;
debug(poodinisVerbose) {
printDebugAutowiringCandidate(qualifiedInstanceType, &qualifiedInstance, typeid(Type), &instance, member);
}
}
private QualifierType createOrResolveInstance(MemberType, QualifierType, bool createNew, bool isOptional)(shared(DependencyContainer) container) { private QualifierType createOrResolveInstance(MemberType, QualifierType, bool createNew, bool isOptional)(shared(DependencyContainer) container) {
static if (createNew) { static if (createNew) {
auto instanceFactory = new InstanceFactory(); auto instanceFactory = new InstanceFactory();