reactant-di
Version:
A dependency injection lib for Reactant
77 lines (74 loc) • 2.37 kB
JavaScript
import 'reflect-metadata';
import { METADATA_KEY } from '../constants.js';
/**
* ## Description
*
* You can get a decorator `@lazy(serviceIdentifier)` with `getLazyDecorator((serviceIdentifier) => container.get(serviceIdentifier))`,
* and use it on any one dependency property that you need to lazily get.
*
* ## Example
*
* ```ts
* let container: Container;
* const lazy = getLazyDecorator((serviceIdentifier) =>
* container.get(serviceIdentifier)
* );
*
* @injectable()
* class Foo {
* public get test() {
* return 'test';
* }
* }
*
* @injectable()
* class Bar {
* @lazy('foo')
* foo?: Foo;
* }
*
* container = createContainer({
* ServiceIdentifiers: new Map(),
* });
*
* const bar = container.get(Bar);
*
* container.bind('foo').to(Foo);
* expect(bar.foo?.test).toBe('test');
* ```
*/
var getLazyDecorator = function (getService) {
return function (serviceIdentifier, enableCache) {
if (enableCache === void 0) { enableCache = true; }
return function (target, key) {
function getter() {
if (enableCache && !Reflect.hasMetadata(METADATA_KEY.lazy, this, key)) {
var service = getService(serviceIdentifier, this);
if (service !== null) {
Reflect.defineMetadata(METADATA_KEY.lazy, service, this, key);
}
}
if (Reflect.hasMetadata(METADATA_KEY.lazy, this, key)) {
return Reflect.getMetadata(METADATA_KEY.lazy, this, key);
}
return getService(serviceIdentifier, this);
}
function setter(newVal) {
if (enableCache) {
Reflect.defineMetadata(METADATA_KEY.lazy, newVal, this, key);
}
else {
console.warn("\n Disable cache and the property ".concat(key.toString(), " in class \"").concat(this.constructor.name, "\" instance failed to set value.\n "));
}
}
// It should be compatible with the TS decorator and the babel decorator
return {
configurable: true,
enumerable: true,
get: getter,
set: setter,
};
};
};
};
export { getLazyDecorator };