src/instantiators/Singleton.js

Summary

Maintainability
A
0 mins
Test Coverage
const AbstractInstantiator = require('./AbstractInstantiator');

/**
 * The singleton instantiator will create a maximum of one instance of a module per dependency tree.
 * When you request an already instantiated module, the singleton instantiator will return you the
 * already instantiated module.
 *
 * @author Wolfgang Felbermeier (@f3lang)
 */
class Singleton extends AbstractInstantiator {

    /**
     * @param {ObjectManager} objectManager
     * @param {PrototypeWrapper} prototypeWrapper
     */
    constructor(objectManager, prototypeWrapper) {
        super();
        this.cache = {};
        this.objectManager = objectManager;
        this.prototypeWrapper = prototypeWrapper;
        this.requestCollection = [];
    }

    getInstance(path, config, root, requestId) {
        if(this.cache[path + ":" + root]) {
            return this.cache[path + ":" + root];
        }
        if(super.requestIsCircular(path, root, requestId)) {
            return;
        }
        let params = this.objectManager.getModuleParams(config.injectMap, root, requestId);
        delete require.cache[require.resolve(path)];
        let resolvedModuleData = this.prototypeWrapper.require(path, root, requestId);
        let module = resolvedModuleData.targetPrototype;
        module.tree = root;
        let instance = new module(...params);
        this.cache[path + ":" + root] = instance;
        if(resolvedModuleData.originalChain) {
            this.prototypeWrapper.restoreOriginalPrototypeChain(resolvedModuleData.originalChain);
        }
        return instance;
    }

}

module.exports = Singleton;
module.exports.inject = ['ObjectManager'];