DI test prototype
by Aleksey P
JavaScript
"use strict";
function IoC() {
let services = {}; // services registration options
let self = this;
this.register = function(service, options) {
if (typeof(service) !== "function")
throw new Error("Service is not a function: " + service);
if (typeof(options) === "undefined") {
options = {};
};
setDefaultOptions(options);
let name = service.name;
if (services.hasOwnProperty(name))
throw new Error("Service already has been registered: " + name);
options.__service = service;
services[name] = options;
return function() {
return self.resolve(name);
};
};
this.resolve = function(name) {
if (!services.hasOwnProperty(name))
throw new Error("Service can not be resolved: " + name);
let options = services[name];
let service = options.__service;
let usedServices = getParamNames(service).map(self.resolve);
if (options.lifetime == "transient") {
return function() {
return new function() {
return service.apply(this, usedServices);
};
};
};
if (options.lifetime == "singleton") {
return function() {
return options.__instance || (options.__instance = new function() {
return service.apply(this, usedServices);
});
};
};
throw new Error("Service can not be resolved: " + name);
};
this.check = function() {
Object.keys(services).forEach(checkUsedServicesExist);
Object.keys(services).forEach(checkCycle);
};
function checkUsedServicesExist(name) {
getUsedServices(name).map(self.resolve);
};
let getUsedServices = name => getParamNames(services[name].__service);
function checkCycle(name) {
let chains = [[name]];
let i = 0;
while (i < chains.length) {
let currentChain = chains[i];
let currentName = currentChain[currentChain.length - 1];
let currentUsed = getUsedServices(currentName);
currentChain.forEach(x => {
if...