@artus/injection
Advanced tools
Comparing version 0.3.1 to 0.4.0
@@ -9,2 +9,2 @@ export declare const CLASS_CONSTRUCTOR: unique symbol; | ||
export declare const INJECT_HANDLER_ARGS: unique symbol; | ||
export declare const MAP_TYPE: unique symbol; | ||
export declare const LAZY_HANDLER: unique symbol; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.MAP_TYPE = exports.INJECT_HANDLER_ARGS = exports.INJECT_HANDLER_PROPS = exports.CLASS_TAG = exports.EXECUTION_CONTEXT_KEY = exports.CLASS_ASYNC_INIT_METHOD = exports.CLASS_CONSTRUCTOR_ARGS = exports.CLASS_PROPERTY = exports.CLASS_CONSTRUCTOR = void 0; | ||
exports.LAZY_HANDLER = exports.INJECT_HANDLER_ARGS = exports.INJECT_HANDLER_PROPS = exports.CLASS_TAG = exports.EXECUTION_CONTEXT_KEY = exports.CLASS_ASYNC_INIT_METHOD = exports.CLASS_CONSTRUCTOR_ARGS = exports.CLASS_PROPERTY = exports.CLASS_CONSTRUCTOR = void 0; | ||
exports.CLASS_CONSTRUCTOR = Symbol.for('injection:constructor'); | ||
@@ -12,3 +12,3 @@ exports.CLASS_PROPERTY = Symbol.for('injection:property'); | ||
exports.INJECT_HANDLER_ARGS = Symbol.for('injection:handler_args'); | ||
exports.MAP_TYPE = Symbol('map_type'); | ||
exports.LAZY_HANDLER = Symbol('injection:lazy_handler'); | ||
//# sourceMappingURL=constant.js.map |
@@ -1,2 +0,2 @@ | ||
import { ContainerType, Identifier, InjectableMetadata, InjectableDefinition, HandlerFunction } from './types'; | ||
import { ContainerType, InjectOptions, Identifier, InjectableMetadata, InjectableDefinition, HandlerFunction } from './types'; | ||
export default class Container implements ContainerType { | ||
@@ -8,4 +8,3 @@ private registry; | ||
constructor(name: string); | ||
get<T = unknown>(id: Identifier<T>): T; | ||
getAsync<T = unknown>(id: Identifier<T>): Promise<T>; | ||
get<T = unknown>(id: Identifier<T>, options?: InjectOptions): T; | ||
set(options: Partial<InjectableDefinition>): this; | ||
@@ -15,3 +14,2 @@ getDefinition<T = unknown>(id: Identifier<T>): InjectableMetadata<T> | undefined; | ||
getByTag(tag: string): unknown[]; | ||
getByTagAsync(tag: string): Promise<unknown[]>; | ||
registerHandler(name: string | symbol, handler: HandlerFunction): void; | ||
@@ -21,11 +19,7 @@ getHandler(name: string | symbol): CallableFunction | undefined; | ||
protected getValue(md: InjectableMetadata): any; | ||
protected getValueAsync(md: InjectableMetadata): Promise<any>; | ||
protected getMetadata(id: Identifier): InjectableMetadata | undefined; | ||
private getDefinedMetaData; | ||
private resolveParams; | ||
private resolveParamsAsync; | ||
private handleProps; | ||
private handlePropsAsync; | ||
private handleTag; | ||
private resolveHandler; | ||
} |
@@ -7,2 +7,3 @@ "use strict"; | ||
const error_1 = require("./error"); | ||
const lazy_helper_1 = require("./lazy_helper"); | ||
class Container { | ||
@@ -14,6 +15,10 @@ constructor(name) { | ||
this.handlerMap = new Map(); | ||
this.registerHandler(constant_1.LAZY_HANDLER, lazy_helper_1.lazyHandler); | ||
} | ||
get(id) { | ||
const md = this.getMetadata(id); | ||
get(id, options = {}) { | ||
const md = this.getDefinition(id); | ||
if (!md) { | ||
if (options.noThrow) { | ||
return options.defaultValue; | ||
} | ||
throw new error_1.NotFoundError(id); | ||
@@ -23,12 +28,2 @@ } | ||
} | ||
async getAsync(id) { | ||
var _a; | ||
const md = this.getMetadata(id); | ||
if (!md) { | ||
throw new error_1.NotFoundError(id); | ||
} | ||
const instance = await this.getValueAsync(md); | ||
await ((_a = instance[md.initMethod]) === null || _a === void 0 ? void 0 : _a.call(instance)); | ||
return instance; | ||
} | ||
set(options) { | ||
@@ -62,3 +57,2 @@ var _a, _b; | ||
if (md.id !== type) { | ||
md[constant_1.MAP_TYPE] = type; | ||
this.registry.set(type, md); | ||
@@ -70,3 +64,2 @@ } | ||
if (md.eager && md.scope !== types_1.ScopeEnum.TRANSIENT) { | ||
// TODO: handle async | ||
this.get(md.id); | ||
@@ -77,3 +70,3 @@ } | ||
getDefinition(id) { | ||
return this.getMetadata(id); | ||
return this.registry.get(id); | ||
} | ||
@@ -88,6 +81,2 @@ getInjectableByTag(tag) { | ||
} | ||
getByTagAsync(tag) { | ||
const clazzes = this.getInjectableByTag(tag); | ||
return Promise.all(clazzes.map(clazz => this.getAsync(clazz))); | ||
} | ||
registerHandler(name, handler) { | ||
@@ -124,29 +113,2 @@ this.handlerMap.set(name, handler); | ||
} | ||
async getValueAsync(md) { | ||
var _a; | ||
if (!(0, util_1.isUndefined)(md.value)) { | ||
return md.value; | ||
} | ||
let value; | ||
if (md.factory) { | ||
value = await md.factory(md.id, this); | ||
} | ||
if (!value && md.type) { | ||
const clazz = md.type; | ||
const params = await this.resolveParamsAsync(clazz, md.constructorArgs); | ||
value = new clazz(...params); | ||
await this.handlePropsAsync(value, (_a = md.properties) !== null && _a !== void 0 ? _a : []); | ||
} | ||
if (md.scope === types_1.ScopeEnum.SINGLETON) { | ||
md.value = value; | ||
} | ||
return value; | ||
} | ||
getMetadata(id) { | ||
const md = this.registry.get(id); | ||
if (md && md[constant_1.MAP_TYPE]) { | ||
return this.registry.get(md[constant_1.MAP_TYPE]); | ||
} | ||
return md; | ||
} | ||
getDefinedMetaData(options) { | ||
@@ -191,25 +153,6 @@ var _a, _b, _c; | ||
? this.resolveHandler(arg.handler, arg.id) | ||
: this.get(arg.id); | ||
: this.get(arg.id, { noThrow: arg.noThrow, defaultValue: arg.defaultValue }); | ||
}); | ||
return params; | ||
} | ||
async resolveParamsAsync(clazz, args) { | ||
var _a; | ||
const params = []; | ||
if (!args || !args.length) { | ||
args = ((_a = (0, util_1.getParamMetadata)(clazz)) !== null && _a !== void 0 ? _a : []).map((ele, index) => ({ | ||
id: ele, | ||
index, | ||
})); | ||
} | ||
await Promise.all(args.map(async (arg) => { | ||
if ((0, util_1.isPrimitiveFunction)(arg.id)) { | ||
return; | ||
} | ||
params[arg.index] = arg.handler | ||
? await this.resolveHandler(arg.handler, arg.id) | ||
: await this.getAsync(arg.id); | ||
})); | ||
return params; | ||
} | ||
handleProps(instance, props) { | ||
@@ -219,12 +162,5 @@ props.forEach(prop => { | ||
? this.resolveHandler(prop.handler, prop.id) | ||
: this.get(prop.id); | ||
: this.get(prop.id, { noThrow: prop.noThrow, defaultValue: prop.defaultValue }); | ||
}); | ||
} | ||
async handlePropsAsync(instance, props) { | ||
await Promise.all(props.map(async (prop) => { | ||
instance[prop.propertyName] = prop.handler | ||
? await this.resolveHandler(prop.handler, prop.id) | ||
: await this.getAsync(prop.id); | ||
})); | ||
} | ||
handleTag(target) { | ||
@@ -231,0 +167,0 @@ let tags = Reflect.getOwnMetadata(constant_1.CLASS_TAG, target); |
@@ -1,2 +0,3 @@ | ||
import { Identifier } from '../types'; | ||
export declare function Inject(id?: Identifier): (target: any, propertyKey: string | symbol, index?: number) => void; | ||
import { InjectOptions, Identifier } from '../types'; | ||
export declare function Inject(id?: Identifier): any; | ||
export declare function Inject(options?: InjectOptions): any; |
@@ -7,3 +7,4 @@ "use strict"; | ||
const error_1 = require("../error"); | ||
function Inject(id) { | ||
function Inject(idOrOptions) { | ||
const options = ((0, util_1.isObject)(idOrOptions) ? idOrOptions : { id: idOrOptions }); | ||
return (target, propertyKey, index) => { | ||
@@ -13,3 +14,3 @@ if ((0, util_1.isObject)(target)) { | ||
} | ||
let propertyType = id; | ||
let propertyType = options.id; | ||
if (!propertyType && propertyKey) { | ||
@@ -27,3 +28,3 @@ propertyType = (0, util_1.getDesignTypeMetadata)(target.prototype, propertyKey); | ||
const metadata = ((0, util_1.getMetadata)(constant_1.CLASS_CONSTRUCTOR_ARGS, target) || []); | ||
metadata.push({ id: propertyType, index }); | ||
metadata.push(Object.assign(Object.assign({}, options), { id: propertyType, index, handler: options.lazy ? constant_1.LAZY_HANDLER : undefined })); | ||
(0, util_1.setMetadata)(constant_1.CLASS_CONSTRUCTOR_ARGS, metadata, target); | ||
@@ -33,3 +34,3 @@ return; | ||
const metadata = ((0, util_1.getMetadata)(constant_1.CLASS_PROPERTY, target) || []); | ||
metadata.push({ id: propertyType, propertyName: propertyKey }); | ||
metadata.push(Object.assign(Object.assign({}, options), { id: propertyType, propertyName: propertyKey, handler: options.lazy ? constant_1.LAZY_HANDLER : undefined })); | ||
(0, util_1.setMetadata)(constant_1.CLASS_PROPERTY, metadata, target); | ||
@@ -36,0 +37,0 @@ }; |
@@ -9,4 +9,3 @@ "use strict"; | ||
return (target) => { | ||
var _a; | ||
(0, util_1.setMetadata)(constant_1.CLASS_CONSTRUCTOR, { id: (options === null || options === void 0 ? void 0 : options.id) || target, scope: (_a = options === null || options === void 0 ? void 0 : options.scope) !== null && _a !== void 0 ? _a : types_1.ScopeEnum.SINGLETON }, target); | ||
(0, util_1.setMetadata)(constant_1.CLASS_CONSTRUCTOR, Object.assign({ id: target, scope: types_1.ScopeEnum.SINGLETON }, options), target); | ||
}; | ||
@@ -13,0 +12,0 @@ } |
@@ -8,6 +8,5 @@ import Container from './container'; | ||
get<T = unknown>(id: Identifier<T>): T; | ||
getAsync<T = unknown>(id: Identifier<T>): Promise<T>; | ||
getCtx(): any; | ||
getHandler(name: string): HandlerFunction | undefined; | ||
getHandler(name: string | symbol): HandlerFunction | undefined; | ||
private setValue; | ||
} |
@@ -17,3 +17,3 @@ "use strict"; | ||
var _a; | ||
const md = (_a = this.getMetadata(id)) !== null && _a !== void 0 ? _a : this.parent.getDefinition(id); | ||
const md = (_a = this.getDefinition(id)) !== null && _a !== void 0 ? _a : this.parent.getDefinition(id); | ||
if (!md) { | ||
@@ -28,15 +28,2 @@ throw new error_1.NotFoundError(id); | ||
} | ||
async getAsync(id) { | ||
var _a, _b; | ||
const md = (_a = this.getMetadata(id)) !== null && _a !== void 0 ? _a : this.parent.getDefinition(id); | ||
if (!md) { | ||
throw new error_1.NotFoundError(id); | ||
} | ||
const instance = await this.getValueAsync(md); | ||
await ((_b = instance[md.initMethod]) === null || _b === void 0 ? void 0 : _b.call(instance)); | ||
if (md.scope === types_1.ScopeEnum.EXECUTION) { | ||
this.setValue(md, instance); | ||
} | ||
return instance; | ||
} | ||
getCtx() { | ||
@@ -43,0 +30,0 @@ return this.ctx; |
@@ -5,3 +5,2 @@ import Container from './container'; | ||
export * from './types'; | ||
export * from './decorator/init'; | ||
export * from './decorator/inject'; | ||
@@ -8,0 +7,0 @@ export * from './decorator/injectable'; |
@@ -10,3 +10,2 @@ "use strict"; | ||
tslib_1.__exportStar(require("./types"), exports); | ||
tslib_1.__exportStar(require("./decorator/init"), exports); | ||
tslib_1.__exportStar(require("./decorator/inject"), exports); | ||
@@ -13,0 +12,0 @@ tslib_1.__exportStar(require("./decorator/injectable"), exports); |
@@ -11,2 +11,8 @@ export declare type Constructable<T = unknown> = new (...args: any[]) => T; | ||
} | ||
export interface InjectOptions { | ||
id?: Identifier; | ||
noThrow?: boolean; | ||
defaultValue?: any; | ||
lazy?: boolean; | ||
} | ||
export interface InjectableOption { | ||
@@ -27,7 +33,7 @@ id?: Identifier; | ||
eager?: boolean; | ||
factory?: CallableFunction; | ||
factory?: (id: Identifier, container?: ContainerType) => any; | ||
} | ||
export interface InjectableMetadata<T = any> extends InjectableDefinition<T> { | ||
properties?: any[]; | ||
constructorArgs?: any[]; | ||
properties?: ReflectMetadataType[]; | ||
constructorArgs?: ReflectMetadataType[]; | ||
initMethod?: string | symbol; | ||
@@ -39,2 +45,5 @@ } | ||
index?: number; | ||
lazy?: boolean; | ||
defaultValue?: boolean; | ||
noThrow?: boolean; | ||
propertyName?: string | symbol; | ||
@@ -45,3 +54,2 @@ handler?: string | symbol; | ||
get<T>(id: Identifier<T>): T; | ||
getAsync<T>(id: Identifier<T>): Promise<T>; | ||
set(options: Partial<InjectableDefinition>): this; | ||
@@ -51,4 +59,5 @@ getDefinition(id: Identifier): InjectableMetadata | undefined; | ||
getByTag(tag: string): any[]; | ||
registerHandler(name: string, handler: HandlerFunction): void; | ||
getHandler(name: string): HandlerFunction | undefined; | ||
registerHandler(name: string | symbol, handler: HandlerFunction): void; | ||
getHandler(name: string | symbol): HandlerFunction | undefined; | ||
hasValue(options: Partial<InjectableDefinition>): boolean; | ||
} | ||
@@ -55,0 +64,0 @@ /** |
@@ -26,2 +26,3 @@ import { ReflectMetadataType } from './types'; | ||
export declare function addTag(tag: string, target: any): void; | ||
export declare function isInjectable(target: any): boolean; | ||
export declare function isClass(clazz: any): boolean; | ||
@@ -28,0 +29,0 @@ export declare function isNumber(value: any): boolean; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isPrimitiveFunction = exports.isFunction = exports.isObject = exports.isUndefined = exports.isNumber = exports.isClass = exports.addTag = exports.getDesignTypeMetadata = exports.getParamMetadata = exports.recursiveGetMetadata = exports.setMetadata = exports.getMetadata = void 0; | ||
exports.isPrimitiveFunction = exports.isFunction = exports.isObject = exports.isUndefined = exports.isNumber = exports.isClass = exports.isInjectable = exports.addTag = exports.getDesignTypeMetadata = exports.getParamMetadata = exports.recursiveGetMetadata = exports.setMetadata = exports.getMetadata = void 0; | ||
const constant_1 = require("./constant"); | ||
@@ -74,2 +74,6 @@ const functionPrototype = Object.getPrototypeOf(Function); | ||
exports.addTag = addTag; | ||
function isInjectable(target) { | ||
return Reflect.hasOwnMetadata(constant_1.CLASS_CONSTRUCTOR, target); | ||
} | ||
exports.isInjectable = isInjectable; | ||
function isClass(clazz) { | ||
@@ -76,0 +80,0 @@ if (typeof clazz !== 'function') { |
{ | ||
"name": "@artus/injection", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "A IoC Implemention for Artus.", | ||
@@ -13,3 +13,6 @@ "main": "lib/index.js", | ||
"prepublish": "npm run build", | ||
"test": "jest --coverage --config ./jest.config.js" | ||
"test": "jest --coverage --config ./jest.config.js", | ||
"ci": "npm run lint && npm run test", | ||
"lint:fix": "eslint . --ext .ts --fix", | ||
"lint": "eslint . --ext .ts" | ||
}, | ||
@@ -27,2 +30,3 @@ "repository": { | ||
"devDependencies": { | ||
"@artus/eslint-config-artus": "^0.0.1", | ||
"@artus/tsconfig": "0.0.1", | ||
@@ -32,2 +36,3 @@ "@types/jest": "^27.4.1", | ||
"eslint": "^7.32.0", | ||
"eslint-plugin-import": "^2.26.0", | ||
"jest": "^27.5.1", | ||
@@ -34,0 +39,0 @@ "reflect-metadata": "^0.1.13", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
51232
11
799