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,10 +53,13 @@ class DependencyContainer {
|
||||||
writeln(format("DEBUG: Register type %s (as %s)", concreteType.toString(), registeredType.toString()));
|
writeln(format("DEBUG: Register type %s (as %s)", concreteType.toString(), registeredType.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto existingRegistration = getRegistration(registeredType, concreteType);
|
auto existingCandidates = registeredType in registrations;
|
||||||
|
if (existingCandidates) {
|
||||||
|
auto existingRegistration = getRegistration(*existingCandidates, concreteType);
|
||||||
if (existingRegistration) {
|
if (existingRegistration) {
|
||||||
return existingRegistration;
|
return existingRegistration;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Registration newRegistration = new Registration(registeredType, concreteType);
|
Registration newRegistration = new Registration(registeredType, concreteType);
|
||||||
newRegistration.singleInstance();
|
newRegistration.singleInstance();
|
||||||
|
@ -64,23 +67,27 @@ class DependencyContainer {
|
||||||
return newRegistration;
|
return newRegistration;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Registration getRegistration(TypeInfo registeredType, TypeInfo_Class concreteType) {
|
private Registration getRegistration(Registration[] candidates, TypeInfo concreteType) {
|
||||||
auto existingCandidates = registeredType in registrations;
|
foreach(existingRegistration ; candidates) {
|
||||||
if (existingCandidates) {
|
writeln("DEBUG: Test type " ~ existingRegistration.instantiatableType.toString() ~ " with " ~ concreteType.toString());
|
||||||
foreach(existingRegistration ; *existingCandidates) {
|
|
||||||
if (existingRegistration.instantiatableType == concreteType) {
|
if (existingRegistration.instantiatableType == concreteType) {
|
||||||
return existingRegistration;
|
return existingRegistration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegistrationType resolve(RegistrationType)() {
|
public RegistrationType resolve(RegistrationType)() {
|
||||||
|
return resolve!(RegistrationType, RegistrationType)();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegistrationType resolve(RegistrationType, QualifierType : RegistrationType)() {
|
||||||
TypeInfo resolveType = typeid(RegistrationType);
|
TypeInfo resolveType = typeid(RegistrationType);
|
||||||
|
TypeInfo qualifierType = typeid(QualifierType);
|
||||||
|
|
||||||
debug {
|
debug {
|
||||||
writeln("DEBUG: Resolving type " ~ resolveType.toString());
|
writeln("DEBUG: Resolving type " ~ resolveType.toString() ~ " with qualifier " ~ qualifierType.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto candidates = resolveType in registrations;
|
auto candidates = resolveType in registrations;
|
||||||
|
@ -88,8 +95,7 @@ class DependencyContainer {
|
||||||
throw new ResolveException("Type not registered.", resolveType);
|
throw new ResolveException("Type not registered.", resolveType);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto registration = (*candidates)[0];
|
Registration registration = getQualifiedRegistration(resolveType, qualifierType, *candidates);
|
||||||
|
|
||||||
RegistrationType instance = cast(RegistrationType) registration.getInstance();
|
RegistrationType instance = cast(RegistrationType) registration.getInstance();
|
||||||
|
|
||||||
if (!autowireStack.canFind(registration)) {
|
if (!autowireStack.canFind(registration)) {
|
||||||
|
@ -101,6 +107,19 @@ class DependencyContainer {
|
||||||
return instance;
|
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() {
|
public void clearAllRegistrations() {
|
||||||
registrations.destroy();
|
registrations.destroy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,3 +119,14 @@ public Registration existingInstance(Registration registration, Object instance)
|
||||||
registration.registationScope = new ExistingInstanceScope(instance);
|
registration.registationScope = new ExistingInstanceScope(instance);
|
||||||
return registration;
|
return registration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string toConcreteTypeListString(Registration[] registrations) {
|
||||||
|
auto concreteTypeListString = "";
|
||||||
|
foreach (registration ; registrations) {
|
||||||
|
if (!concreteTypeListString.length) {
|
||||||
|
concreteTypeListString ~= ", ";
|
||||||
|
}
|
||||||
|
concreteTypeListString ~= registration.instantiatableType.toString();
|
||||||
|
}
|
||||||
|
return concreteTypeListString;
|
||||||
|
}
|
||||||
|
|
|
@ -290,4 +290,30 @@ version(unittest) {
|
||||||
|
|
||||||
assert(firstRegistration is secondRegistration, "First registration is not the same as the second of equal types");
|
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