jsdoc/packages/jsdoc-core/lib/dependencies.js
Jeff Williams 29b64a4638 feature(@jsdoc/core): make the dependency provider more flexible
You can now register classes and factory functions, either as singletons or not.
2021-10-21 17:35:30 -07:00

69 lines
1.6 KiB
JavaScript

const Bottle = require('bottlejs');
/**
* Container for JSDoc classes, objects, and values that can be injected into other modules.
*
* @alias module:@jsdoc/core.deps
*/
class Dependencies {
constructor() {
// This class provides a lightweight facade for the `bottlejs` package.
this._bottle = new Bottle();
this._container = this._bottle.container;
}
get(name) {
const dep = this._container[name];
if (dep === undefined) {
throw new Error(`No dependency registered for the name "${name}"`);
}
return dep;
}
registerClass(name, constructor, ...deps) {
this._bottle.service(name, constructor, ...deps);
// Remove the cached provider.
this._bottle.middleware(name, (_, next) => {
this._bottle.resetProviders([name]);
next();
});
}
registerFactory(name, factory, ...deps) {
const realFactory = () => {
const args = deps.map((dep) => this.get(dep));
return factory(...args);
};
this._bottle.serviceFactory(name, realFactory, ...deps);
// Remove the cached provider.
this._bottle.middleware(name, (_, next) => {
this._bottle.resetProviders([name]);
next();
});
}
registerSingleton(name, constructor, ...deps) {
this._bottle.service(name, constructor, ...deps);
}
registerSingletonFactory(name, factory, ...deps) {
const realFactory = () => {
const args = deps.map((dep) => this.get(dep));
return factory(...args);
};
this._bottle.factory(name, realFactory);
}
registerValue(name, value) {
this._bottle.value(name, value);
}
}
module.exports = Dependencies;