import {getInstanceMethods} from "../../util" import {ComponentScopes, ComponentType} from "../../enum" import {IComponent, IDao} from "../../type/interface" import {ConstructorType, PojoType} from "../../type/type" import ContextContainer from "../ContextContainer" import Interceptor from "../interceptor/Interceptor" /** * InstanceBuilder * 根据注解映射关系,构造实例 * 目前只支持两种方式的实例构造方式:单例和原型,默认为单例模式 * - 单例模式:共用一个实例(数据共享) * - 原型模式:每次都会创建一个实例(数据安全) */ export default class InstanceBuilder{ private interceptor = new Interceptor() private fakeComponentCache: Map = new Map() private static instanceCache: Map = new Map() public getFakeComponentFromCache(id: string): PojoType{ return this.fakeComponentCache.get(id) } public createInstance(component: IComponent, fake: boolean = false, idn: string = ''): PojoType{ let {cost, props, scope, isAop, packageName, type} = component if(fake){ scope = ComponentScopes.PROTOTYPE } let instance: any = null if(scope === ComponentScopes.SINGLETON){ const cacheInstance = InstanceBuilder.instanceCache.get(cost) if(cacheInstance){ instance = cacheInstance }else{ instance = new cost() InstanceBuilder.instanceCache.set(cost, instance) } }else{ if(fake){ if(type === ComponentType.DAO){ const cache = this.fakeComponentCache.get(idn) if(cache){ instance = cache }else{ instance = new cost() this.fakeComponentCache.set(idn, instance) } }else{ instance = new cost() } }else{ instance = new cost() } } const {ownMethods = [], prototypeMethods = []} = getInstanceMethods(instance) const instanceMethods = [...ownMethods, ...prototypeMethods] instanceMethods.forEach((method: Function) => { ( method).__caller__ = instance }) instance.meta || (instance.meta = {component}) if(props && Array.isArray(props) && props.length > 0){ props.forEach((prop: PojoType): void => { const propName: string = Object.keys(prop)[0] const propComponent: IComponent = prop[propName] const propInstance = this.createInstance(propComponent, fake, idn) instance[propName] = propInstance }) } return instance } public build(): void{ const entrys = > ContextContainer.getResource('entrys') || [] ContextContainer.setResource('entrys', entrys.map((entry: IComponent): PojoType => { return this.createInstance(entry) })) this.interceptor.handler(this) } }