@mooncake/container
Version:
DI(dependency injection) container for JavaScript and TypeScript.
182 lines • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SYMBOL_INJECT_META = Symbol.for('@mooncake/container:inject');
exports.SYMBOL_BIND_META = Symbol.for('@mooncake/container:bind');
function getInjectMetas(target) {
return Reflect.getMetadata(exports.SYMBOL_INJECT_META, target) || [];
}
exports.getInjectMetas = getInjectMetas;
function addInjectMeta(target, m) {
const arr = Reflect.getMetadata(exports.SYMBOL_INJECT_META, target);
if (arr) {
arr.push(m);
}
else {
Reflect.defineMetadata(exports.SYMBOL_INJECT_META, [m], target);
}
}
function getBindActions(target) {
return Reflect.getMetadata(exports.SYMBOL_BIND_META, target) || [];
}
exports.getBindActions = getBindActions;
function addBindAction(target, action) {
let arr = Reflect.getMetadata(exports.SYMBOL_BIND_META, target);
if (!arr) {
arr = [];
Reflect.defineMetadata(exports.SYMBOL_BIND_META, arr, target);
}
arr.push(action);
}
/**
* Inject optional, undefined will be inject when can not resolve dependency
*
* @export
* @param {ID<any>} [id]
* @returns
*/
function InjectOptional(option) {
if (!option) {
return Inject();
}
if (typeof option !== 'object') {
return Inject({ id: option, required: false });
}
else {
return Inject(Object.assign(option, { required: false }));
}
}
exports.InjectOptional = InjectOptional;
/**
* Inject with container
*
* @export
* @param {ID<any>} [id]
* @returns
*/
function Inject(option) {
let id;
const opt = { required: true };
if (typeof option === 'object') {
id = option.id;
Object.assign(opt, option);
}
else if (option) {
id = option;
}
return function (target, prop, index) {
addInjectMeta(target, {
required: opt.required,
scope: opt.scope,
id: id,
property: prop,
index: index
});
};
}
exports.Inject = Inject;
/**
* Inject with custom rules
*
* @export
* @param {(container: ContainerResolver) => any} resolve
* @returns
*/
function InjectRaw(resolveMethod, opt = { required: true }) {
return function (target, prop, index) {
addInjectMeta(target, {
required: opt.required,
scope: opt.scope,
resolver: resolveMethod,
property: prop,
index: index
});
};
}
exports.InjectRaw = InjectRaw;
/**
* customize bind Action
*
* @export
* @template T
* @param {BindMethod<T>} action
* @returns
*/
function BindAction(action) {
return function (target) {
addBindAction(target, action);
};
}
exports.BindAction = BindAction;
function Alias(id, fromId, opt) {
opt = Object.assign({ singleton: true, scope: 'root' }, opt);
return function (target) {
const action = (clz, c) => c.bindAlias(id, fromId || target, opt);
addBindAction(target, action);
};
}
exports.Alias = Alias;
function Factory(factory, opt) {
opt = Object.assign({ singleton: true, scope: 'root' }, opt);
return function (target) {
const action = (clz, c) => {
c.bindFactory(target, factory);
};
addBindAction(target, action);
};
}
exports.Factory = Factory;
/**
* bind a implement class for this class
*
* @export
* @template T
* @param {() => Constructor<T>} implementClassGetter
* @param {BindOption} [opt]
* @returns
*/
function Implement(implementClassGetter, opt) {
opt = Object.assign({ singleton: true, scope: 'root' }, opt);
return function (target) {
const action = (clz, c) => {
c.bindClassWithId(target, implementClassGetter());
};
addBindAction(target, action);
};
}
exports.Implement = Implement;
function Service(id, opt) {
return function (target) {
const defaultOpt = {
singleton: true, scope: 'root'
};
let _id = target;
if (!id) {
opt = defaultOpt;
}
else if (typeof id === 'object') {
opt = Object.assign(defaultOpt, id);
}
else {
_id = id;
opt = Object.assign(defaultOpt, opt);
}
const action = (clz, c) => c.bindClassWithId(_id, clz, opt);
addBindAction(target, action);
};
}
exports.Service = Service;
/**
* alias of Service. singleton alwas be true
*
* @export
* @param {Pick<BindOption, 'scope'>} [opt={ scope: 'root' }]
* @returns
*/
function Singleton(opt = { scope: 'root' }) {
return Service({
singleton: true,
scope: opt.scope || 'root'
});
}
exports.Singleton = Singleton;
//# sourceMappingURL=decorators.js.map