@@ -19,13 +19,20 @@ const _enableTracing = false;
1919declare var Proxy : any ;
2020const _canUseProxy = typeof Proxy === 'function' ;
2121
22+ class CyclicDependencyError extends Error {
23+ constructor ( graph : Graph < any > ) {
24+ super ( 'cyclic dependency between services' ) ;
25+ this . message = graph . toString ( ) ;
26+ }
27+ }
28+
2229export class InstantiationService implements IInstantiationService {
2330
2431 _serviceBrand : any ;
2532
26- protected readonly _services : ServiceCollection ;
27- protected readonly _strict : boolean ;
28- protected readonly _parent ?: InstantiationService ;
33+ private readonly _services : ServiceCollection ;
34+ private readonly _strict : boolean ;
35+ private readonly _parent ?: InstantiationService ;
2936
3037 constructor ( services : ServiceCollection = new ServiceCollection ( ) , strict : boolean = false , parent ?: InstantiationService ) {
3138 this . _services = services ;
@@ -143,27 +150,19 @@ export class InstantiationService implements IInstantiationService {
143150 type Triple = { id : ServiceIdentifier < any > , desc : SyncDescriptor < any > , _trace : Trace } ;
144151 const graph = new Graph < Triple > ( data => data . id . toString ( ) ) ;
145152
146- function throwCycleError ( ) {
147- const err = new Error ( '[createInstance] cyclic dependency between services' ) ;
148- err . message = graph . toString ( ) ;
149- throw err ;
150- }
151-
152- let count = 0 ;
153+ let cycleCount = 0 ;
153154 const stack = [ { id, desc, _trace } ] ;
154155 while ( stack . length ) {
155156 const item = stack . pop ( ) ! ;
156157 graph . lookupOrInsertNode ( item ) ;
157158
158- // TODO@joh use the graph to find a cycle
159- // a weak heuristic for cycle checks
160- if ( count ++ > 100 ) {
161- throwCycleError ( ) ;
159+ // a weak but working heuristic for cycle checks
160+ if ( cycleCount ++ > 100 ) {
161+ throw new CyclicDependencyError ( graph ) ;
162162 }
163163
164164 // check all dependencies for existence and if they need to be created first
165- let dependencies = _util . getServiceDependencies ( item . desc . ctor ) ;
166- for ( let dependency of dependencies ) {
165+ for ( let dependency of _util . getServiceDependencies ( item . desc . ctor ) ) {
167166
168167 let instanceOrDesc = this . _getServiceInstanceOrDescriptor ( dependency . id ) ;
169168 if ( ! instanceOrDesc && ! dependency . optional ) {
@@ -179,18 +178,18 @@ export class InstantiationService implements IInstantiationService {
179178 }
180179
181180 while ( true ) {
182- let roots = graph . roots ( ) ;
181+ const roots = graph . roots ( ) ;
183182
184183 // if there is no more roots but still
185184 // nodes in the graph we have a cycle
186185 if ( roots . length === 0 ) {
187186 if ( ! graph . isEmpty ( ) ) {
188- throwCycleError ( ) ;
187+ throw new CyclicDependencyError ( graph ) ;
189188 }
190189 break ;
191190 }
192191
193- for ( let { data } of roots ) {
192+ for ( const { data } of roots ) {
194193 // create instance and overwrite the service collections
195194 const instance = this . _createServiceInstanceWithOwner ( data . id , data . desc . ctor , data . desc . staticArguments , data . desc . supportsDelayedInstantiation , data . _trace ) ;
196195 this . _setServiceInstance ( data . id , instance ) ;
0 commit comments