import { interfaces } from "inversify" ; import { IConfig } from "../api/IConfig" ; import { IContext } from "../api/IContext" ; import { IInjector } from "../api/IInjector" ; import { ILogger } from "../api/ILogger" ; import { IMatcher } from "../api/IMatcher" ; import { LifecycleEvent } from "../api/LifecycleEvent" ; import { ClassMatcher } from "./ClassMatcher" ; import { ObjectMatcher } from "./ObjectMatcher" ; import { ObjectProcessor } from "./ObjectProcessor" ; import { instantiateUnmapped } from "./instantiateUnmapped" ; private export class ConfigManager { private _objectProcessor : ObjectProcessor = new ObjectProcessor ( ) ; private _configs : Map < any , boolean > = new Map < any , boolean > ( ) ; private _queue : any [ ] = [ ] ; private _injector : IInjector ; private _logger : ILogger ; private _initialized : boolean = false ; private _context : IContext ; private constructor ( context ) { this . _context = context ; this . _injector = context . injector ; this . _logger = context . getLogger ( this ) ; this . addConfigHandler ( new ClassMatcher ( ) , this . handleClass . bind ( this ) ) ; this . addConfigHandler ( new ObjectMatcher ( ) , this . handleObject . bind ( this ) ) ; context . addEventListener ( LifecycleEvent . INITIALIZE , this . initialize , this , false , - 100 ) ; } param config public addConfig ( config ) { if ( ! this . _configs . get ( config ) ) { this . _configs . set ( config , true ) ; this . _objectProcessor . processObject ( config ) ; } } param matcher param handler public addConfigHandler ( matcher , handler ) { this . _objectProcessor . addObjectHandler ( matcher , handler ) ; } /**
     * Destroy
     */ public destroy ( ) { this . _context . removeEventListener ( LifecycleEvent . INITIALIZE , this . initialize ) ; this . _objectProcessor . removeAllHandlers ( ) ; this . _queue . length = 0 ; this . _configs . clear ( ) ; } private initialize ( event ) { if ( ! this . _initialized ) { this . _initialized = true ; this . processQueue ( ) ; } } private handleClass ( type ) { if ( this . _initialized ) { this . _logger . debug ( "Already initialized. Instantiating config class {0}" , [ type ] ) ; this . processClass ( type ) ; } else { this . _logger . debug ( "Not yet initialized. Queuing config class {0}" , [ type ] ) ; this . _queue . push ( type ) ; } } private handleObject ( object ) { if ( this . _initialized ) { this . _logger . debug ( "Already initialized. Injecting into config object {0}" , [ object ] ) ; this . processObject ( object ) ; } else { this . _logger . debug ( "Not yet initialized. Queuing config object {0}" , [ object ] ) ; this . _queue . push ( object ) ; } } private processQueue ( ) { for ( let i in this . _queue ) { if ( this . _queue . hasOwnProperty ( i ) ) { let config = this . _queue [ i ] ; if ( typeof config === "function" ) { this . _logger . debug ( "Now initializing. Instantiating config class {0}" , [ config ] ) ; this . processClass ( config ) ; } else { this . _logger . debug ( "Now initializing. Injecting into config object {0}" , [ config ] ) ; this . processObject ( config ) ; } } } this . _queue . length = 0 ; } private processClass ( type ) { let config = instantiateUnmapped < IConfig > ( this . _injector , type ) ; if ( config ) { config . configure ( ) ; } } private processObject ( object ) { let config = < IConfig > object ; if ( config && config . configure ) { config . configure ( ) ; } } }