Remove static context from container

This commit is contained in:
Mike Bierlee 2014-05-20 00:23:25 +02:00
parent da1f604ef7
commit 27a50a53cf
2 changed files with 37 additions and 35 deletions

View file

@ -26,30 +26,27 @@ class ResolveException : Exception {
class Container { class Container {
private static Registration[TypeInfo] registrations; private Registration[TypeInfo] registrations;
private static bool _globalTypeValidityCheckEnabled = true; private bool _typeValidityCheckEnabled = true;
@property public static void globalTypeValidityCheckEnabled(bool enabled) { @property public void typeValidityCheckEnabled(bool enabled) {
_globalTypeValidityCheckEnabled = enabled; _typeValidityCheckEnabled = enabled;
} }
@property public static bool globalTypeValidityCheckEnabled() { @property public bool typeValidityCheckEnabled() {
return _globalTypeValidityCheckEnabled; return _typeValidityCheckEnabled;
} }
private this() { public Registration register(ConcreteType)() {
}
public static Registration register(ConcreteType)() {
return register!(ConcreteType, ConcreteType)(); return register!(ConcreteType, ConcreteType)();
} }
public static Registration register(InterfaceType, ConcreteType)(bool checkTypeValidity = true) { public Registration register(InterfaceType, ConcreteType)(bool checkTypeValidity = true) {
TypeInfo registeredType = typeid(InterfaceType); TypeInfo registeredType = typeid(InterfaceType);
TypeInfo_Class instantiatableType = typeid(ConcreteType); TypeInfo_Class instantiatableType = typeid(ConcreteType);
if (globalTypeValidityCheckEnabled && checkTypeValidity) { if (typeValidityCheckEnabled && checkTypeValidity) {
checkValidity!(InterfaceType)(registeredType, instantiatableType); checkValidity!(InterfaceType)(registeredType, instantiatableType);
} }
@ -58,7 +55,7 @@ class Container {
return newRegistration; return newRegistration;
} }
private static void checkValidity(InterfaceType)(TypeInfo registeredType, TypeInfo_Class instanceType) { private 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());
@ -66,7 +63,7 @@ class Container {
} }
} }
public static ClassType resolve(ClassType)() { public ClassType resolve(ClassType)() {
TypeInfo resolveType = typeid(ClassType); TypeInfo resolveType = typeid(ClassType);
Registration* registration = resolveType in registrations; Registration* registration = resolveType in registrations;
if (!registration) { if (!registration) {
@ -75,7 +72,7 @@ class Container {
return cast(ClassType) registration.getInstance(); return cast(ClassType) registration.getInstance();
} }
public static void clearRegistrations() { public void clearRegistrations() {
registrations.clear(); registrations.clear();
} }
} }

View file

@ -14,55 +14,60 @@ version(unittest) {
unittest { unittest {
// Test register concrete type // Test register concrete type
Container.clearRegistrations(); auto container = new Container();
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(); auto container = new Container();
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");
assert(cast(TestClass) actualInstance, "Resolved class is not the same type as expected"); assert(cast(TestClass) actualInstance, "Resolved class is not the same type as expected");
} }
unittest { unittest {
// Test register interface // Test register interface
Container.clearRegistrations(); auto container = new Container();
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");
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");
} }
unittest { unittest {
// Test register unrelated types fails // Test register unrelated types fails
Container.clearRegistrations(); auto container = new Container();
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(); auto container = new Container();
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 { unittest {
// Test resolve non-registered type // Test resolve non-registered type
Container.clearRegistrations(); 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");
} }
unittest { unittest {
// Test register unrelated class with disable global type validity disabled // Test register unrelated class with disable global type validity disabled
bool currentSetting = Container.globalTypeValidityCheckEnabled; auto container = new Container();
Container.globalTypeValidityCheckEnabled = false; container.typeValidityCheckEnabled = false;
assertNotThrown!RegistrationException(container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types while disabling global type validity fails");
}
assertNotThrown!RegistrationException(Container.register!(UnrelatedClass, TestClass)(), "Registering unrelated types while disabling global type validity fails"); unittest {
// Test clear registrations
Container.globalTypeValidityCheckEnabled = currentSetting; auto container = new Container();
container.register!(TestClass)();
container.clearRegistrations();
assertThrown!ResolveException(container.resolve!(TestClass)(), "Resolving cleared type does not fail");
} }
} }