import { ViewContainerRef } from '@angular/core' ; import { ComponentRef , Type } from '@angular/core' ; import { InjectionService } from '../injection/injection.service' ; import { PartialBindings } from './partial-bindings.interface' ; export abstract class InjectionRegistryService < T = any > { protected defaults : PartialBindings = { } ; protected components = new Map < any , Array < ComponentRef < T > > > ( ) ; protected abstract type : Type < T > ; constructor ( protected readonly injectionService ) { } getByType ( type = this . type ) { return this . components . get ( type ) ; } create ( bindings ) { return this . createByType ( this . type , bindings ) ; } createByType ( type , bindings ) { const location = ( bindings as any ) . parentContainer ; bindings = this . assignDefaults ( bindings ) ; const component = this . injectComponent ( type , bindings , location ) ; this . register ( type , component ) ; return component ; } destroy ( instance ) { const compsByType = this . components . get ( instance . componentType ) ; if ( compsByType && compsByType . length ) { const idx = compsByType . indexOf ( instance ) ; if ( idx > - 1 ) { const component = compsByType [ idx ] ; component . destroy ( ) ; compsByType . splice ( idx , 1 ) ; } } } destroyAll ( ) { this . destroyByType ( this . type ) ; } destroyByType ( type ) { const comps = this . components . get ( type ) ; if ( comps && comps . length ) { let i = comps . length - 1 ; while ( i >= 0 ) { this . destroy ( comps [ i -- ] ) ; } } } protected injectComponent ( type , bindings , location ? ) { return this . injectionService . appendComponent ( type , bindings , location ) ; } protected assignDefaults ( bindings ) { const inputs = { ... this . defaults . inputs } ; const outputs = { ... this . defaults . outputs } ; if ( ! bindings . inputs && ! bindings . outputs ) { bindings = { inputs : bindings } ; } if ( inputs ) { bindings . inputs = { ... inputs , ... bindings . inputs } ; } if ( outputs ) { bindings . outputs = { ... outputs , ... bindings . outputs } ; } return bindings ; } protected register ( type , component ) { if ( ! this . components . has ( type ) ) { this . components . set ( type , [ ] ) ; } const types = this . components . get ( type ) ; types . push ( component ) ; } }