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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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) {
|
||||
alias MemberType = typeof(__traits(getMember, instance, member));
|
||||
|
||||
enum assignNewInstance = hasUDA!(__traits(getMember, instance, member), AssignNewInstance);
|
||||
|
||||
static if (isDynamicArray!MemberType) {
|
||||
alias MemberElementType = ElementType!MemberType;
|
||||
auto instances = container.resolveAll!MemberElementType;
|
||||
|
@ -120,12 +137,12 @@ private void autowireMember(string member, Type)(shared(DependencyContainer) con
|
|||
MemberType qualifiedInstance;
|
||||
static if (is(autowireAttribute == Autowire!T, T) && !is(autowireAttribute.qualifier == UseMemberType)) {
|
||||
alias QualifierType = typeof(autowireAttribute.qualifier);
|
||||
qualifiedInstance = container.resolve!(MemberType, QualifierType);
|
||||
qualifiedInstance = createOrResolveInstance!(MemberType, QualifierType, assignNewInstance)(container);
|
||||
debug(poodinisVerbose) {
|
||||
qualifiedInstanceType = typeid(QualifierType);
|
||||
}
|
||||
} else {
|
||||
qualifiedInstance = container.resolve!(MemberType);
|
||||
qualifiedInstance = createOrResolveInstance!(MemberType, MemberType, assignNewInstance)(container);
|
||||
}
|
||||
|
||||
__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.
|
||||
*
|
||||
|
|
|
@ -63,6 +63,11 @@ version(unittest) {
|
|||
@Autowire
|
||||
public InterfaceA[] components;
|
||||
}
|
||||
class ComponentCharlie {
|
||||
@Autowire
|
||||
@AssignNewInstance
|
||||
public ComponentA componentA;
|
||||
}
|
||||
|
||||
// Test autowiring concrete type to existing instance
|
||||
unittest {
|
||||
|
@ -170,4 +175,17 @@ version(unittest) {
|
|||
|
||||
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