mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Add type validity check
This commit is contained in:
parent
535f5df482
commit
cc3c0d5f6d
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue