Replace type validity check with template parameter specialization

This commit is contained in:
Mike Bierlee 2014-05-31 23:37:02 +02:00
parent b78e05455d
commit 121d871572
2 changed files with 2 additions and 53 deletions

View file

@ -23,42 +23,21 @@ class Container {
private static Container instance; private static Container instance;
private Registration[TypeInfo] registrations; private Registration[TypeInfo] registrations;
private bool _typeValidityCheckEnabled = true;
@property public void typeValidityCheckEnabled(bool enabled) {
_typeValidityCheckEnabled = enabled;
}
@property public bool typeValidityCheckEnabled() {
return _typeValidityCheckEnabled;
}
public Registration register(ConcreteType)() { public Registration register(ConcreteType)() {
return register!(ConcreteType, ConcreteType)(false); return register!(ConcreteType, ConcreteType)();
} }
public Registration register(InterfaceType, ConcreteType)(bool checkTypeValidity = true) { public Registration register(InterfaceType, ConcreteType : InterfaceType)() {
TypeInfo registeredType = typeid(InterfaceType); TypeInfo registeredType = typeid(InterfaceType);
TypeInfo_Class instantiatableType = typeid(ConcreteType); TypeInfo_Class instantiatableType = typeid(ConcreteType);
if (typeValidityCheckEnabled && checkTypeValidity) {
checkValidity!(InterfaceType)(registeredType, instantiatableType);
}
Registration newRegistration = new Registration(registeredType, instantiatableType); Registration newRegistration = new Registration(registeredType, instantiatableType);
newRegistration.singleInstance(); newRegistration.singleInstance();
registrations[registeredType] = newRegistration; registrations[registeredType] = newRegistration;
return newRegistration; return newRegistration;
} }
private void checkValidity(InterfaceType)(TypeInfo registeredType, TypeInfo_Class instanceType) {
InterfaceType instanceCanBeCastToInterface = cast(InterfaceType) instanceType.create();
if (!instanceCanBeCastToInterface) {
string errorMessage = format("%s cannot be cast to %s.", instanceType.name, registeredType.toString());
throw new RegistrationException(errorMessage, registeredType, instanceType);
}
}
public RegistrationType resolve(RegistrationType)() { public RegistrationType resolve(RegistrationType)() {
TypeInfo resolveType = typeid(RegistrationType); TypeInfo resolveType = typeid(RegistrationType);
Registration* registration = resolveType in registrations; Registration* registration = resolveType in registrations;

View file

@ -61,31 +61,12 @@ version(unittest) {
assert(cast(TestInterface) actualInstance, "Resolved class is not the same type as expected"); assert(cast(TestInterface) actualInstance, "Resolved class is not the same type as expected");
} }
// Test register unrelated types fails
unittest {
auto container = new Container();
assertThrown!RegistrationException(container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types does not fail");
}
// Test register unrelated types with disabled check on registration
unittest {
auto container = new Container();
assertNotThrown!RegistrationException(container.register!(UnrelatedClass, TestClass)(false), "Registering unrelated types while disabling type validity fails");
}
// Test resolve non-registered type // Test resolve non-registered type
unittest { unittest {
auto container = new Container(); auto container = new Container();
assertThrown!ResolveException(container.resolve!(TestClass)(), "Resolving non-registered type does not fail"); assertThrown!ResolveException(container.resolve!(TestClass)(), "Resolving non-registered type does not fail");
} }
// Test register unrelated class with disable global type validity disabled
unittest {
auto container = new Container();
container.typeValidityCheckEnabled = false;
assertNotThrown!RegistrationException(container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types while disabling global type validity fails");
}
// Test clear registrations // Test clear registrations
unittest { unittest {
auto container = new Container(); auto container = new Container();
@ -101,17 +82,6 @@ version(unittest) {
assert(instance1 is instance2, "getInstance does not return the same instance"); assert(instance1 is instance2, "getInstance does not return the same instance");
} }
// Test registering concrete type does not do a validity check
unittest {
auto container = new Container();
assert(container.typeValidityCheckEnabled);
try {
container.register!(FailOnCreationClass)();
} catch (Exception) {
assert(false, "Registering concrete type executed a validity check");
}
}
// Test resolve single instance for type // Test resolve single instance for type
unittest { unittest {
auto container = new Container(); auto container = new Container();