mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Add ability to assign new instance to autowired member regardless of registration scope
This commit is contained in:
parent
1551f9e012
commit
3e11ff1e92
|
@ -64,6 +64,21 @@ struct Autowire(QualifierType = UseMemberType) {
|
||||||
QualifierType qualifier;
|
QualifierType qualifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UDA for annotating class members to be autowired with a new instance regardless of their registration scope.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*---
|
||||||
|
* class Car {
|
||||||
|
* @Autowire
|
||||||
|
* @AssignNewInstance
|
||||||
|
* public Antenna antenna;
|
||||||
|
* }
|
||||||
|
*---
|
||||||
|
* antenna will always be assigned a new instance of class Antenna.
|
||||||
|
*/
|
||||||
|
struct AssignNewInstance {}
|
||||||
|
|
||||||
private void printDebugAutowiredInstance(TypeInfo instanceType, void* instanceAddress) {
|
private void printDebugAutowiredInstance(TypeInfo instanceType, void* instanceAddress) {
|
||||||
writeln(format("DEBUG: Autowiring members of [%s@%s]", instanceType, instanceAddress));
|
writeln(format("DEBUG: Autowiring members of [%s@%s]", instanceType, instanceAddress));
|
||||||
}
|
}
|
||||||
|
@ -105,6 +120,8 @@ private void autowireMember(string member, Type)(shared(DependencyContainer) con
|
||||||
if (__traits(getMember, instance, member) is null) {
|
if (__traits(getMember, instance, member) is null) {
|
||||||
alias MemberType = typeof(__traits(getMember, instance, member));
|
alias MemberType = typeof(__traits(getMember, instance, member));
|
||||||
|
|
||||||
|
enum assignNewInstance = hasUDA!(__traits(getMember, instance, member), AssignNewInstance);
|
||||||
|
|
||||||
static if (isDynamicArray!MemberType) {
|
static if (isDynamicArray!MemberType) {
|
||||||
alias MemberElementType = ElementType!MemberType;
|
alias MemberElementType = ElementType!MemberType;
|
||||||
auto instances = container.resolveAll!MemberElementType;
|
auto instances = container.resolveAll!MemberElementType;
|
||||||
|
@ -120,12 +137,12 @@ private void autowireMember(string member, Type)(shared(DependencyContainer) con
|
||||||
MemberType qualifiedInstance;
|
MemberType qualifiedInstance;
|
||||||
static if (is(autowireAttribute == Autowire!T, T) && !is(autowireAttribute.qualifier == UseMemberType)) {
|
static if (is(autowireAttribute == Autowire!T, T) && !is(autowireAttribute.qualifier == UseMemberType)) {
|
||||||
alias QualifierType = typeof(autowireAttribute.qualifier);
|
alias QualifierType = typeof(autowireAttribute.qualifier);
|
||||||
qualifiedInstance = container.resolve!(MemberType, QualifierType);
|
qualifiedInstance = createOrResolveInstance!(MemberType, QualifierType, assignNewInstance)(container);
|
||||||
debug(poodinisVerbose) {
|
debug(poodinisVerbose) {
|
||||||
qualifiedInstanceType = typeid(QualifierType);
|
qualifiedInstanceType = typeid(QualifierType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qualifiedInstance = container.resolve!(MemberType);
|
qualifiedInstance = createOrResolveInstance!(MemberType, MemberType, assignNewInstance)(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
__traits(getMember, instance, member) = qualifiedInstance;
|
__traits(getMember, instance, member) = qualifiedInstance;
|
||||||
|
@ -142,6 +159,15 @@ private void autowireMember(string member, Type)(shared(DependencyContainer) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private QualifierType createOrResolveInstance(MemberType, QualifierType, bool createNew)(shared(DependencyContainer) container) {
|
||||||
|
static if (createNew) {
|
||||||
|
auto instanceFactory = new NewInstanceScope(typeid(MemberType));
|
||||||
|
return cast(MemberType) instanceFactory.getInstance();
|
||||||
|
} else {
|
||||||
|
return container.resolve!(MemberType, QualifierType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Autowire the given instance using the globally available dependency container.
|
* Autowire the given instance using the globally available dependency container.
|
||||||
*
|
*
|
||||||
|
|
|
@ -63,6 +63,11 @@ version(unittest) {
|
||||||
@Autowire
|
@Autowire
|
||||||
public InterfaceA[] components;
|
public InterfaceA[] components;
|
||||||
}
|
}
|
||||||
|
class ComponentCharlie {
|
||||||
|
@Autowire
|
||||||
|
@AssignNewInstance
|
||||||
|
public ComponentA componentA;
|
||||||
|
}
|
||||||
|
|
||||||
// Test autowiring concrete type to existing instance
|
// Test autowiring concrete type to existing instance
|
||||||
unittest {
|
unittest {
|
||||||
|
@ -170,4 +175,17 @@ version(unittest) {
|
||||||
|
|
||||||
assert(lord.components.length == 2, "Dynamic array was not autowired");
|
assert(lord.components.length == 2, "Dynamic array was not autowired");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test autowiring new instance of singleinstance registration with newInstance UDA
|
||||||
|
unittest {
|
||||||
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
|
container.register!ComponentA;
|
||||||
|
|
||||||
|
auto regularComponentA = container.resolve!ComponentA;
|
||||||
|
auto charlie = new ComponentCharlie();
|
||||||
|
|
||||||
|
container.autowire(charlie);
|
||||||
|
|
||||||
|
assert(charlie.componentA !is regularComponentA, "Autowiring class with AssignNewInstance did not yield a different instance");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue