Throw exception when resolving non-registered type

This commit is contained in:
Mike Bierlee 2014-05-16 02:04:23 +02:00
parent 27d86ce8c7
commit 423f21230a
2 changed files with 29 additions and 2 deletions

View file

@ -1,6 +1,7 @@
module poodinis.container; module poodinis.container;
import std.string; import std.string;
import std.array;
struct Registration { struct Registration {
TypeInfo registeredType = null; TypeInfo registeredType = null;
@ -17,6 +18,12 @@ class RegistrationException : Exception {
} }
} }
class ResolveException : Exception {
this(string message, TypeInfo resolveType) {
super(format("Exception while resolving type %s: %s", resolveType.toString(), message));
}
}
class Container { class Container {
private static Registration[TypeInfo] registrations; private static Registration[TypeInfo] registrations;
@ -44,12 +51,21 @@ class Container {
private static void checkValidity(InterfaceType)(TypeInfo registeredType, TypeInfo_Class instanceType) { private static void checkValidity(InterfaceType)(TypeInfo registeredType, TypeInfo_Class instanceType) {
InterfaceType instanceCanBeCastToInterface = cast(InterfaceType) instanceType.create(); InterfaceType instanceCanBeCastToInterface = cast(InterfaceType) instanceType.create();
if (!instanceCanBeCastToInterface) { if (!instanceCanBeCastToInterface) {
string errorMessage = format("%s cannot be cast to %s", instanceType.name, registeredType.toString()); string errorMessage = format("%s cannot be cast to %s.", instanceType.name, registeredType.toString());
throw new RegistrationException(errorMessage, registeredType, instanceType); throw new RegistrationException(errorMessage, registeredType, instanceType);
} }
} }
public static ClassType resolve(ClassType)() { public static ClassType resolve(ClassType)() {
return cast(ClassType) registrations[typeid(ClassType)].getInstance(); TypeInfo resolveType = typeid(ClassType);
Registration* registration = resolveType in registrations;
if (!registration) {
throw new ResolveException("Type not registered.", resolveType);
}
return cast(ClassType) registration.getInstance();
}
public static void clearRegistrations() {
registrations.clear();
} }
} }

View file

@ -14,12 +14,14 @@ version(unittest) {
unittest { unittest {
// Test register concrete type // Test register concrete type
Container.clearRegistrations();
auto registration = Container.register!(TestClass)(); auto registration = Container.register!(TestClass)();
assert(registration.registeredType == typeid(TestClass), "Type of registered type not the same"); assert(registration.registeredType == typeid(TestClass), "Type of registered type not the same");
} }
unittest { unittest {
// Test resolve registered type // Test resolve registered type
Container.clearRegistrations();
Container.register!(TestClass)(); Container.register!(TestClass)();
TestClass actualInstance = Container.resolve!(TestClass)(); TestClass actualInstance = Container.resolve!(TestClass)();
assert(actualInstance !is null, "Resolved type is null"); assert(actualInstance !is null, "Resolved type is null");
@ -28,6 +30,7 @@ version(unittest) {
unittest { unittest {
// Test register interface // Test register interface
Container.clearRegistrations();
Container.register!(TestInterface, TestClass)(); Container.register!(TestInterface, TestClass)();
TestInterface actualInstance = Container.resolve!(TestInterface)(); TestInterface actualInstance = Container.resolve!(TestInterface)();
assert(actualInstance !is null, "Resolved type is null"); assert(actualInstance !is null, "Resolved type is null");
@ -36,12 +39,20 @@ version(unittest) {
unittest { unittest {
// Test register unrelated types fails // Test register unrelated types fails
Container.clearRegistrations();
assertThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types does not fail"); assertThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types does not fail");
} }
unittest { unittest {
// Test register unrelated types with disabled check on registration // Test register unrelated types with disabled check on registration
Container.clearRegistrations();
assertNotThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(false), "Registering unrelated types while disabling type validity fails"); assertNotThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(false), "Registering unrelated types while disabling type validity fails");
} }
unittest {
// Test resolve non-registered type
Container.clearRegistrations();
assertThrown!ResolveException(Container.resolve!(TestClass)(), "Resolving non-registered type does not fail");
}
} }