mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Add ability to resolve type which has multiple registrations by qualifier
This commit is contained in:
parent
d6e3043c7d
commit
8b9c8d2774
|
@ -53,9 +53,12 @@ class DependencyContainer {
|
|||
writeln(format("DEBUG: Register type %s (as %s)", concreteType.toString(), registeredType.toString()));
|
||||
}
|
||||
|
||||
auto existingRegistration = getRegistration(registeredType, concreteType);
|
||||
if (existingRegistration) {
|
||||
return existingRegistration;
|
||||
auto existingCandidates = registeredType in registrations;
|
||||
if (existingCandidates) {
|
||||
auto existingRegistration = getRegistration(*existingCandidates, concreteType);
|
||||
if (existingRegistration) {
|
||||
return existingRegistration;
|
||||
}
|
||||
}
|
||||
|
||||
Registration newRegistration = new Registration(registeredType, concreteType);
|
||||
|
@ -64,13 +67,11 @@ class DependencyContainer {
|
|||
return newRegistration;
|
||||
}
|
||||
|
||||
private Registration getRegistration(TypeInfo registeredType, TypeInfo_Class concreteType) {
|
||||
auto existingCandidates = registeredType in registrations;
|
||||
if (existingCandidates) {
|
||||
foreach(existingRegistration ; *existingCandidates) {
|
||||
if (existingRegistration.instantiatableType == concreteType) {
|
||||
return existingRegistration;
|
||||
}
|
||||
private Registration getRegistration(Registration[] candidates, TypeInfo concreteType) {
|
||||
foreach(existingRegistration ; candidates) {
|
||||
writeln("DEBUG: Test type " ~ existingRegistration.instantiatableType.toString() ~ " with " ~ concreteType.toString());
|
||||
if (existingRegistration.instantiatableType == concreteType) {
|
||||
return existingRegistration;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,9 +79,15 @@ class DependencyContainer {
|
|||
}
|
||||
|
||||
public RegistrationType resolve(RegistrationType)() {
|
||||
return resolve!(RegistrationType, RegistrationType)();
|
||||
}
|
||||
|
||||
public RegistrationType resolve(RegistrationType, QualifierType : RegistrationType)() {
|
||||
TypeInfo resolveType = typeid(RegistrationType);
|
||||
TypeInfo qualifierType = typeid(QualifierType);
|
||||
|
||||
debug {
|
||||
writeln("DEBUG: Resolving type " ~ resolveType.toString());
|
||||
writeln("DEBUG: Resolving type " ~ resolveType.toString() ~ " with qualifier " ~ qualifierType.toString());
|
||||
}
|
||||
|
||||
auto candidates = resolveType in registrations;
|
||||
|
@ -88,8 +95,7 @@ class DependencyContainer {
|
|||
throw new ResolveException("Type not registered.", resolveType);
|
||||
}
|
||||
|
||||
auto registration = (*candidates)[0];
|
||||
|
||||
Registration registration = getQualifiedRegistration(resolveType, qualifierType, *candidates);
|
||||
RegistrationType instance = cast(RegistrationType) registration.getInstance();
|
||||
|
||||
if (!autowireStack.canFind(registration)) {
|
||||
|
@ -101,6 +107,19 @@ class DependencyContainer {
|
|||
return instance;
|
||||
}
|
||||
|
||||
private Registration getQualifiedRegistration(TypeInfo resolveType, TypeInfo qualifierType, Registration[] candidates) {
|
||||
if (resolveType == qualifierType) {
|
||||
if (candidates.length > 1) {
|
||||
string candidateList = candidates.toConcreteTypeListString();
|
||||
throw new ResolveException("Multiple qualified candidates available: " ~ candidateList ~ ". Please specify qualifier.", resolveType);
|
||||
}
|
||||
|
||||
return candidates[0];
|
||||
}
|
||||
|
||||
return getRegistration(candidates, qualifierType);
|
||||
}
|
||||
|
||||
public void clearAllRegistrations() {
|
||||
registrations.destroy();
|
||||
}
|
||||
|
|
|
@ -119,3 +119,14 @@ public Registration existingInstance(Registration registration, Object instance)
|
|||
registration.registationScope = new ExistingInstanceScope(instance);
|
||||
return registration;
|
||||
}
|
||||
|
||||
public string toConcreteTypeListString(Registration[] registrations) {
|
||||
auto concreteTypeListString = "";
|
||||
foreach (registration ; registrations) {
|
||||
if (!concreteTypeListString.length) {
|
||||
concreteTypeListString ~= ", ";
|
||||
}
|
||||
concreteTypeListString ~= registration.instantiatableType.toString();
|
||||
}
|
||||
return concreteTypeListString;
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ version(unittest) {
|
|||
auto autowiredInstance = container.resolve!AutowiredClass;
|
||||
assert(componentInstance.autowiredClass is autowiredInstance, "Member is not autowired upon resolving");
|
||||
}
|
||||
|
||||
|
||||
// Test circular autowiring
|
||||
unittest {
|
||||
auto container = new DependencyContainer();
|
||||
|
@ -290,4 +290,30 @@ version(unittest) {
|
|||
|
||||
assert(firstRegistration is secondRegistration, "First registration is not the same as the second of equal types");
|
||||
}
|
||||
|
||||
// Test resolve registration with multiple qualifiers
|
||||
unittest {
|
||||
auto container = new DependencyContainer();
|
||||
container.register!(Color, Blue);
|
||||
container.register!(Color, Red);
|
||||
try {
|
||||
container.resolve!Color;
|
||||
} catch (ResolveException e) {
|
||||
return;
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// Test resolve registration with multiple qualifiers using a qualifier
|
||||
unittest {
|
||||
auto container = new DependencyContainer();
|
||||
container.register!(Color, Blue);
|
||||
container.register!(Color, Red);
|
||||
auto blueInstance = container.resolve!(Color, Blue);
|
||||
auto redInstance = container.resolve!(Color, Red);
|
||||
|
||||
assert(blueInstance !is redInstance, "Resolving type with multiple, different registrations yielded the same instance");
|
||||
assert(blueInstance !is null, "Resolved blue instance to null");
|
||||
assert(redInstance !is null, "Resolved red instance to null");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue