diff --git a/source/poodinis/container.d b/source/poodinis/container.d index cf9b85e..383e01f 100644 --- a/source/poodinis/container.d +++ b/source/poodinis/container.d @@ -1,6 +1,7 @@ module poodinis.container; import std.string; +import std.array; struct Registration { 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 { private static Registration[TypeInfo] registrations; @@ -44,12 +51,21 @@ class Container { 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()); + 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(); + 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(); } } diff --git a/test/poodinis/containertest.d b/test/poodinis/containertest.d index 19242aa..829b4ed 100644 --- a/test/poodinis/containertest.d +++ b/test/poodinis/containertest.d @@ -14,12 +14,14 @@ version(unittest) { unittest { // Test register concrete type + Container.clearRegistrations(); auto registration = Container.register!(TestClass)(); assert(registration.registeredType == typeid(TestClass), "Type of registered type not the same"); } unittest { // Test resolve registered type + Container.clearRegistrations(); Container.register!(TestClass)(); TestClass actualInstance = Container.resolve!(TestClass)(); assert(actualInstance !is null, "Resolved type is null"); @@ -28,6 +30,7 @@ version(unittest) { unittest { // Test register interface + Container.clearRegistrations(); Container.register!(TestInterface, TestClass)(); TestInterface actualInstance = Container.resolve!(TestInterface)(); assert(actualInstance !is null, "Resolved type is null"); @@ -36,12 +39,20 @@ version(unittest) { unittest { // Test register unrelated types fails + Container.clearRegistrations(); assertThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types does not fail"); } unittest { // 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"); } + unittest { + // Test resolve non-registered type + Container.clearRegistrations(); + assertThrown!ResolveException(Container.resolve!(TestClass)(), "Resolving non-registered type does not fail"); + } + } \ No newline at end of file