poodinis/source/poodinis/container.d
2014-06-04 00:16:24 +02:00

84 lines
2.2 KiB
D

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