Destroy registrations when clearing them, invoking their destructors

This commit is contained in:
Mike Bierlee 2014-10-06 13:18:20 +02:00
parent 16e961c43d
commit b0c880a950

View file

@ -1,83 +1,83 @@
/** /**
* Poodinis Dependency Injection Framework * Poodinis Dependency Injection Framework
* Copyright 2014 Mike Bierlee * Copyright 2014 Mike Bierlee
* This software is licensed under the terms of the MIT license. * This software is licensed under the terms of the MIT license.
* The full terms of the license can be found in the LICENSE file. * The full terms of the license can be found in the LICENSE file.
*/ */
module poodinis.container; module poodinis.container;
import std.string; import std.string;
import std.array; import std.array;
import std.algorithm; import std.algorithm;
public import poodinis.registration; public import poodinis.registration;
public import poodinis.autowire; public import poodinis.autowire;
class RegistrationException : Exception { class RegistrationException : Exception {
this(string message, TypeInfo registeredType, TypeInfo_Class instantiatableType) { this(string message, TypeInfo registeredType, TypeInfo_Class instantiatableType) {
super(format("Exception while registering type %s to %s: %s", registeredType.toString(), instantiatableType.name, message)); super(format("Exception while registering type %s to %s: %s", registeredType.toString(), instantiatableType.name, message));
} }
} }
class ResolveException : Exception { class ResolveException : Exception {
this(string message, TypeInfo resolveType) { this(string message, TypeInfo resolveType) {
super(format("Exception while resolving type %s: %s", resolveType.toString(), message)); super(format("Exception while resolving type %s: %s", resolveType.toString(), message));
} }
} }
class Container { class Container {
private static Container instance; private static Container instance;
private Registration[TypeInfo] registrations; private Registration[TypeInfo] registrations;
private Registration*[] autowireStack; private Registration*[] autowireStack;
public Registration register(ConcreteType)() { public Registration register(ConcreteType)() {
return register!(ConcreteType, ConcreteType)(); return register!(ConcreteType, ConcreteType)();
} }
public Registration register(InterfaceType, ConcreteType : InterfaceType)() { public Registration register(InterfaceType, ConcreteType : InterfaceType)() {
TypeInfo registeredType = typeid(InterfaceType); TypeInfo registeredType = typeid(InterfaceType);
TypeInfo_Class instantiatableType = typeid(ConcreteType); TypeInfo_Class instantiatableType = typeid(ConcreteType);
Registration newRegistration = new Registration(registeredType, instantiatableType); Registration newRegistration = new Registration(registeredType, instantiatableType);
newRegistration.singleInstance(); newRegistration.singleInstance();
registrations[registeredType] = newRegistration; registrations[registeredType] = newRegistration;
return newRegistration; return newRegistration;
} }
public RegistrationType resolve(RegistrationType)() { public RegistrationType resolve(RegistrationType)() {
TypeInfo resolveType = typeid(RegistrationType); TypeInfo resolveType = typeid(RegistrationType);
Registration* registration = resolveType in registrations; Registration* registration = resolveType in registrations;
if (!registration) { if (!registration) {
throw new ResolveException("Type not registered.", resolveType); throw new ResolveException("Type not registered.", resolveType);
} }
RegistrationType instance = cast(RegistrationType) registration.getInstance(); RegistrationType instance = cast(RegistrationType) registration.getInstance();
if (!autowireStack.canFind(registration)) { if (!autowireStack.canFind(registration)) {
autowireStack ~= registration; autowireStack ~= registration;
this.autowire!(RegistrationType)(instance); this.autowire!(RegistrationType)(instance);
autowireStack.popBack(); autowireStack.popBack();
} }
return instance; return instance;
} }
public void clearAllRegistrations() { public void clearAllRegistrations() {
registrations = null; registrations.destroy();
} }
public void removeRegistration(RegistrationType)() { public void removeRegistration(RegistrationType)() {
registrations.remove(typeid(RegistrationType)); registrations.remove(typeid(RegistrationType));
} }
public static Container getInstance() { public static Container getInstance() {
if (instance is null) { if (instance is null) {
instance = new Container(); instance = new Container();
} }
return instance; return instance;
} }
} }