Add type validity check

This commit is contained in:
Mike Bierlee 2014-05-16 01:36:17 +02:00
parent 535f5df482
commit cc3c0d5f6d
2 changed files with 34 additions and 7 deletions

View file

@ -1,5 +1,7 @@
module poodinis.container;
import std.string;
struct Registration {
TypeInfo registratedType = null;
TypeInfo_Class instantiatableType = null;
@ -9,6 +11,12 @@ struct Registration {
}
}
class RegistrationException : Exception {
this(string message, TypeInfo registratedType, TypeInfo_Class instantiatableType) {
super(format("Exception while registering type %s to %s: %s", registratedType.toString(), instantiatableType.name, message));
}
}
class Container {
private static Registration[TypeInfo] registrations;
@ -20,12 +28,27 @@ class Container {
return register!(ConcreteType, ConcreteType)();
}
public static Registration register(InterfaceType, ConcreteType)() {
Registration newRegistration = { typeid(InterfaceType), typeid(ConcreteType) };
public static Registration register(InterfaceType, ConcreteType)(bool checkTypeValidity = true) {
TypeInfo registeredType = typeid(InterfaceType);
TypeInfo_Class instantiatableType = typeid(ConcreteType);
if (checkTypeValidity) {
checkValidity!(InterfaceType)(registeredType, instantiatableType);
}
Registration newRegistration = { registeredType, instantiatableType };
registrations[newRegistration.registratedType] = newRegistration;
return newRegistration;
}
private static 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 static ClassType resolve(ClassType)() {
return cast(ClassType) registrations[typeid(ClassType)].getInstance();
}

View file

@ -1,6 +1,6 @@
import poodinis.container;
import std.stdio;
import std.exception;
version(unittest) {
interface TestInterface {
@ -35,9 +35,13 @@ version(unittest) {
}
unittest {
// Test resolve type registered with unrelated type fails
Container.register!(UnrelatedClass, TestClass)();
UnrelatedClass actualInstance = Container.resolve!(UnrelatedClass)();
assert(actualInstance is null, "Resolved type is not null");
// Test register unrelated types fails
assertThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types does not fail");
}
unittest {
// Test register unrelated types with disabled check on registration
assertNotThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(false), "Registering unrelated types while disabling type validity fails");
}
}