export class export class Injector { private type { Injector } memberof public parentInjector : Injector ; private type { Map < any , any > } memberof private readonly providerMap : Map < any , any > = new Map ( ) ; private type { Map < any , any > } memberof private readonly instanceMap : Map < any , any > = new Map ( ) ; memberof constructor ( ) { this . setProviderAndInstance ( Injector , Injector , this ) ; } param { * } key param { * } value memberof public setProvider ( key , value ) { if ( ! this . providerMap . has ( key ) ) this . providerMap . set ( key , value ) ; } param { * } key param { ( number | 'always' ) } bubblingLayer returns { * } memberof public getProvider ( key , bubblingLayer = 'always' ) { if ( this . providerMap . has ( key ) ) return this . providerMap . get ( key ) ; else if ( bubblingLayer !== 0 && this . parentInjector ) return this . parentInjector . getProvider ( key , bubblingLayer === 'always' ? 'always' : ( bubblingLayer - 1 ) ) ; else return undefined ; } param { * } key param { * } value memberof public setInstance ( key , value ) { if ( this . providerMap . has ( key ) ) { if ( ! this . instanceMap . has ( key ) ) this . instanceMap . set ( key , value ) ; } else if ( this . parentInjector ) { this . parentInjector . setInstance ( key , value ) ; } else { throw new Error ( `injector can'n set instance of provider: ${ ( key as any ) . name }` ) ; } } param { * } key param { ( number | 'always' ) } bubblingLayer returns { * } memberof public getInstance ( key , bubblingLayer = 'always' ) { if ( this . providerMap . has ( key ) ) { if ( this . instanceMap . has ( key ) ) return this . instanceMap . get ( key ) ; else return undefined ; } else if ( bubblingLayer !== 0 && this . parentInjector ) { return this . parentInjector . getInstance ( key , bubblingLayer === 'always' ? 'always' : ( bubblingLayer - 1 ) ) ; } else { return undefined ; } } param { * } key param { * } provider param { * } instance memberof public setProviderAndInstance ( key , provider , instance ) { this . setProvider ( key , provider ) ; this . setInstance ( key , instance ) ; } param { * } key param { ( number | 'always' ) } bubblingLayer returns { Injector } memberof public getParentInjectorOfProvider ( key , bubblingLayer = 'always' ) { if ( this . providerMap . has ( key ) ) { return this ; } else if ( bubblingLayer !== 0 && this . parentInjector ) { return this . parentInjector . getParentInjectorOfProvider ( key , bubblingLayer === 'always' ? 'always' : ( bubblingLayer - 1 ) ) ; } else { throw new Error ( `injector can't find parent injector of provider: ${ ( key as any ) . name }` ) ; } } returns { Injector } memberof public fork ( ) { const childInjector = new Injector ( ) ; childInjector . parentInjector = this ; return childInjector ; } } export const rootInjector = new Injector ( ) ;