import { ComponentFactoryResolver , ComponentRef , Injectable , Injector , NgModuleFactoryLoader , Type } from '@angular/core' ; import { DynamicContentOutletErrorComponent } from './dynamic-content-outlet-error.component' ; import { DynamicContentOutletRegistry } from './dynamic-content-outlet.registry' ; type ModuleWithDynamicComponents = Type < any > & { dynamicComponentsMap : { } ; } ; @ Injectable ( ) export class DynamicContentOutletService { constructor ( private componentFactoryResolver , private moduleLoader , private injector ) { } async GetComponent ( componentName ) { const modulePath = this . getModulePathForComponent ( componentName ) ; if ( ! modulePath ) { return this . getDynamicContentErrorComponent ( `Unable to derive modulePath from component: ${ componentName } in dynamic-content.registry.ts` ) ; } try { const moduleFactory = await this . moduleLoader . load ( modulePath ) ; const moduleReference = moduleFactory . create ( this . injector ) ; const componentResolver = moduleReference . componentFactoryResolver ; const componentType = ( moduleFactory . moduleType as ModuleWithDynamicComponents ) . dynamicComponentsMap [ componentName ] ; const componentFactory = componentResolver . resolveComponentFactory ( componentType ) ; return componentFactory . create ( this . injector ) ; } catch ( error ) { console . error ( error . message ) ; return this . getDynamicContentErrorComponent ( `Unable to load module ${ modulePath }.
                Looked up using component: ${ componentName }. Error Details: ${ error . message }` ) ; } } private getModulePathForComponent ( componentName ) { const registryItem = DynamicContentOutletRegistry . find ( i => i . componentName === componentName ) ; if ( registryItem && registryItem . modulePath ) { return `${ registryItem . modulePath }#${ registryItem . moduleName }` ; } return null ; } private getDynamicContentErrorComponent ( errorMessage ) { const factory = this . componentFactoryResolver . resolveComponentFactory ( DynamicContentOutletErrorComponent ) ; const componentRef = factory . create ( this . injector ) ; const instance = < any > componentRef . instance ; instance . errorMessage = errorMessage ; return componentRef ; } }