import { Type , getType } from "tst-reflect" ; import { ServiceCollection } from "./ServiceCollection" ; /**
 * Implementation of IServiceProvider
 */ export class ServiceProvider { /**
     * Service collection
     */ private readonly _serviceCollection : ServiceCollection ; param serviceCollection constructor ( serviceCollection ) { this . _serviceCollection = serviceCollection ; } param type getServices < TDependency > ( type ? ) { if ( type === undefined ) { type = getType < TDependency > ( ) ; } const implementations = Array . from ( this . _serviceCollection . services ) . find ( ( [ dependency ] ) => type . is ( dependency ) ) ?. [ 1 ] ; if ( ! implementations || ! implementations . length ) { throw new Error ( `Type '${ type . fullName }' is not registered.` ) ; } const self = this ; return { [ Symbol . iterator ] : function * ( ) { let ctor , args ; for ( let impl of implementations ) { if ( ! impl . getConstructors ( ) ?. length ) { yield Reflect . construct ( impl . ctor , [ ] ) ; } ctor = impl . getConstructors ( ) . sort ( ( a , b ) => a . parameters . length > b . parameters . length ? 1 : 0 ) [ 0 ] ; args = ctor . parameters . map ( param => self . getService ( param . type ) ) ; yield Reflect . construct ( impl . ctor , args ) ; } } } ; } param type getService < TDependency > ( type ? ) { return this . getServices ( type ?? getType < TDependency > ( ) ) [ Symbol . iterator ] ( ) . next ( ) . value || null ; } }