import {ComponentScopes} from "../enum" import {IComponent, IFile, IResource} from "../type/interface" import {ContextConfigType} from "../type/type" import ContextContainer from "./ContextContainer" import DecorateRegistCenter from "./DecorateRegistCenter" import FileScanner from "./FileScanner" export default class ComponentBuilder{ private config: ContextConfigType = ContextContainer.config private scanComponentsByConfigPath(): ComponentBuilder{ const {scanDirs = []} = this.config const fileScanner = new FileScanner(scanDirs) fileScanner.scanFiles() return this } private buildComponentAbstructPackage(): ComponentBuilder{ const components = DecorateRegistCenter.components const files = FileScanner.files components.forEach((component: IComponent) => { const {packageName = ''} = files.find(file => file.cost === component.cost) component.packageName = packageName }) return this } private buildComponentEntry(): void{ const {scopes, components, aspects, resourceMappings} = DecorateRegistCenter resourceMappings.forEach((mapping: IResource): void => { const {mappingName, propName, caller} = mapping const callerFun = _getComponentByCaller(components, caller) const propFun = _getComponentByMappingName(components, mappingName) callerFun.addProperty({ [propName]: propFun }) }) components.forEach(component => { if(aspects.find(aspect => aspect.cost === component.cost)){ component.isAop = true } const scoper = scopes.find(({cost}) => cost === component.cost) component.scope = scoper ? scoper.scope : ComponentScopes.SINGLETON }) const entrys = components.filter((component: IComponent): boolean => !component.inited) ContextContainer.setResource('entrys', entrys) } public build(){ this .scanComponentsByConfigPath() .buildComponentAbstructPackage() .buildComponentEntry() } } function _getComponentByCaller(components: Array, constructor: Function): IComponent{ return components.find(component => component.cost === constructor) } function _getComponentByMappingName(components: Array, name: string): IComponent{ const component = components.find(component => component.name === name) if(component){ component.inited = true return component } throw new Error('无法通过MappingName名<' + name + '>匹配到任何注册的component') }