papaya
Version:
A minimal dependency injection container
147 lines (146 loc) • 5.05 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* A Papaya container
*/
var Papaya = /** @class */ (function () {
function Papaya() {
this._services = {};
this._functions = {};
this._factories = {};
}
/**
* Gets a service by name.
*
* If the service is not set, will return undefined.
*
* @param name The service name
* @return The service or undefined if it is not set
*/
Papaya.prototype.get = function (name) {
if (this._factories[name]) {
return this._services[name].call(this, this);
}
if (this._functions[name]) {
this._services[name] = this._services[name].call(this, this);
delete this._functions[name];
}
return this._services[name];
};
/**
* Creates a constant by name and value.
*
* @param name The service name
* @param constant The value to be set
*/
Papaya.prototype.constant = function (name, constant) {
this._setService(name, constant);
return this;
};
/**
* Sets a service by name and a service function
*
* The return value of the `service` function will be treated as a singleton
* service meaning it will be initialized the first time it is requested and
* its value will be cached for subsequent requests.
*
* @param name The service name
* @param service The service singleton function or static service
*/
Papaya.prototype.service = function (name, service) {
this._setService(name, service, this._functions);
return this;
};
/**
* Sets a factory service by name and value.
*
* The `factory` function will be called every time the service is requested.
* So if it returns an object, it will create a new object for every request.
*
* @param name The service name
* @param factory The service factory function or static service
*/
Papaya.prototype.factory = function (name, factory) {
this._setService(name, factory, this._factories);
return this;
};
/**
* Extends an existing service and overrides it.
*
* The `extender` function will be called with 2 argument which will be the
* previous value of the service and the Papaya container. If there is no
* existing `name` service, it will throw an error immediately. The
* `extender` function should return the new value for the service that will
* override the existing one.
*
* If `this.extend` is called for a service that was created with
* `this.service`, the resulting service will be a singleton.
*
* If `this.extend` is called for a service that was created with
* `this.factory` the resulting service will be a factory.
*
* If `this.extend` is called for a service that was created with
* `this.constant`, the resulting service will be a singleton.
*
* @param name The service name
* @param extender The service extender function or static service.
*/
Papaya.prototype.extend = function (name, extender) {
var _this = this;
if (!this.has(name)) {
throw new Error("Cannot extend missing service: " + name);
}
var extended = this._services[name];
var protect = false;
var service = function () {
return extender.call(_this, protect ? extended : extended.call(_this, _this), _this);
};
if (this._factories[name]) {
return this.factory(name, service);
}
else {
protect = !this._functions[name];
return this.service(name, service);
}
};
/**
* Register a service provider function.
*
* `provider` will be called with the container as the context. Service
* providers are a good place to register related services using
* `this.service` etc.
*
* @param provider The service provider function
*/
Papaya.prototype.register = function (provider) {
provider.call(this, this);
return this;
};
/**
* Get an array of the regitered service names
*
* @return An array of service names
*/
Papaya.prototype.keys = function () {
return Object.keys(this._services);
};
/**
* Check whether a service has been registered for the given name'
*
* @return True if a service has been registered for `name`, false otherwise.
*/
Papaya.prototype.has = function (name) {
return this._services.hasOwnProperty(name);
};
Papaya.prototype._setService = function (name, service, registry) {
delete this._services[name];
delete this._functions[name];
delete this._factories[name];
if (registry && typeof service === 'function') {
registry[name] = true;
}
this._services[name] = service;
};
return Papaya;
}());
exports.Papaya = Papaya;