import { Bootstrap } from './Bootstrap' ; import { Dependency } from './Dependency' ; import type { DIContainer } from './DIContainer' ; import { RootContainerService } from './entities/RootContainerService' ; import type { IServiceCollection , IServiceInjector } from './IApp' ; import { IDiWrapper , inversifyWrapper } from './inversifyWrapper' ; import type { PluginManifest } from './PluginManifest' ; export class App { private plugins : PluginManifest [ ] ; private diWrapper : IDiWrapper = inversifyWrapper ; constructor ( plugins = [ ] ) { this . plugins = plugins ; const rootContainerService = new RootContainerService ( container => this . registerChildContainer ( container ) ) ; this . getServiceCollection ( ) . addServiceByToken ( RootContainerService , rootContainerService ) ; } registerChildContainer ( container ) { this . diWrapper . registerChildContainer ( container ) ; } addPlugin ( manifest ) { this . plugins . push ( manifest ) ; } getServiceInjector ( ) { return this . diWrapper . injector ; } getServiceCollection ( ) { return this . diWrapper . collection ; } registerServices ( ) { for ( const plugin of this . plugins ) { if ( plugin . providers ?. length ) { plugin . providers . forEach ( provider => { this . diWrapper . collection . addServiceByClass ( provider ) ; } ) ; } } } async initializeServices ( ) { for ( const plugin of this . plugins ) { for ( const service of plugin . providers ) { if ( service . prototype instanceof Bootstrap ) { const serviceInstance = this . diWrapper . injector . getServiceByClass < Bootstrap > ( service ) ; if ( 'register' in serviceInstance ) { await serviceInstance . register ( ) ; } } else if ( service . prototype instanceof Dependency ) { this . diWrapper . injector . getServiceByClass < Bootstrap > ( service ) ; } } } } async loadServices ( ) { for ( const plugin of this . plugins ) { for ( const service of plugin . providers ) { if ( service . prototype instanceof Bootstrap ) { const serviceInstance = this . diWrapper . injector . getServiceByClass < Bootstrap > ( service ) ; if ( 'load' in serviceInstance ) { await serviceInstance . load ( ) ; } } } } } }