11import "reflect-metadata" ;
22
33import {
4+ ClassProvider ,
45 DependencyContainer ,
56 Frequency ,
67 InjectionToken ,
@@ -18,6 +19,7 @@ import { MergeObjects, StringKeyOf, TypedClass } from "../types";
1819import {
1920 DependencyFactory ,
2021 InferDependencies ,
22+ isGeneratedProvider ,
2123} from "../dependencyFactory/DependencyFactory" ;
2224import { EventEmitterProxy } from "../events/EventEmitterProxy" ;
2325
@@ -116,11 +118,9 @@ export type FilterNeverValues<Type extends Record<string, unknown>> = {
116118
117119export type DependenciesFromModules < Modules extends ModulesRecord > =
118120 FilterNeverValues < {
119- [ Key in keyof Modules ] : Modules [ Key ] extends TypedClass < DependencyFactory >
120- ? InferDependencies < InstanceType < Modules [ Key ] > >
121- : Modules [ Key ] extends DependencyFactory
122- ? InferDependencies < Modules [ Key ] >
123- : never ;
121+ [ Key in keyof Modules ] : Modules [ Key ] extends DependencyFactory < any >
122+ ? InferDependencies < Modules [ Key ] >
123+ : never ;
124124 } > ;
125125
126126export type ResolvableModules < Modules extends ModulesRecord > = MergeObjects <
@@ -265,7 +265,7 @@ export class ModuleContainer<Modules extends ModulesRecord>
265265 this . registerAliases ( moduleName , useClass ) ;
266266
267267 if ( this . isDependencyFactory ( useClass ) ) {
268- this . useDependencyFactory ( useClass ) ;
268+ this . useDependencyFactory ( useClass , moduleName ) ;
269269 }
270270 }
271271 } ) ;
@@ -379,7 +379,9 @@ export class ModuleContainer<Modules extends ModulesRecord>
379379 }
380380 }
381381
382- private isDependencyFactory ( type : any ) : type is DependencyFactory {
382+ private isDependencyFactory < T , Class extends ClassProvider < T > [ "useClass" ] > (
383+ type : Class
384+ ) : type is DependencyFactory < T > & Class {
383385 return "dependencies" in type ;
384386 }
385387
@@ -399,9 +401,13 @@ export class ModuleContainer<Modules extends ModulesRecord>
399401 * This will be automatically called for every module, but can also be called
400402 * explicitly to initialize an extra factory
401403 * @param factory
404+ * @param token
402405 * @private
403406 */
404- protected useDependencyFactory ( factory : DependencyFactory ) {
407+ protected useDependencyFactory < T > (
408+ factory : DependencyFactory < T > ,
409+ token ?: string
410+ ) {
405411 const dependencies = factory . dependencies ( ) ;
406412
407413 // eslint-disable-next-line sonarjs/cognitive-complexity
@@ -422,7 +428,20 @@ export class ModuleContainer<Modules extends ModulesRecord>
422428 }
423429
424430 // Find correct provider type and call respective register
425- if ( isValueProvider ( declaration ) ) {
431+ if ( isGeneratedProvider ( declaration ) ) {
432+ if ( token === undefined ) {
433+ throw new Error (
434+ "Cannot use generated provider without injection token"
435+ ) ;
436+ }
437+ // Here we first resolve the instance and then give it to the generator
438+ this . container . register ( key , {
439+ useFactory : instanceCachingFactory ( ( container ) => {
440+ const instance = container . resolve < T > ( token ) ;
441+ return declaration . useGenerated ( instance , this . container ) ;
442+ } ) ,
443+ } ) ;
444+ } else if ( isValueProvider ( declaration ) ) {
426445 this . container . register ( key , declaration ) ;
427446 } else if ( isFactoryProvider ( declaration ) ) {
428447 // this enables us to have a singletoned factory
@@ -442,7 +461,7 @@ export class ModuleContainer<Modules extends ModulesRecord>
442461
443462 // Register static dependencies
444463 if ( this . isDependencyFactory ( declaration . useClass ) ) {
445- this . useDependencyFactory ( declaration . useClass ) ;
464+ this . useDependencyFactory ( declaration . useClass , key ) ;
446465 }
447466 } else if ( isTokenProvider ( declaration ) ) {
448467 this . container . register ( key , declaration , {
@@ -476,10 +495,6 @@ export class ModuleContainer<Modules extends ModulesRecord>
476495 container . reset ( ) ;
477496 return container ;
478497 } ) ;
479-
480- if ( this . isDependencyFactory ( containedModule ) ) {
481- this . useDependencyFactory ( containedModule ) ;
482- }
483498 } ,
484499 { frequency : ModuleContainer . moduleDecorationFrequency }
485500 ) ;
@@ -496,10 +511,10 @@ export class ModuleContainer<Modules extends ModulesRecord>
496511 this . registerValue ( {
497512 ChildContainerProvider : ( ) => this . container . createChildContainer ( ) ,
498513 } ) ;
514+ this . container . register ( "ParentContainer" , { useValue : this } ) ;
499515
500516 // register all provided modules when the container is created
501517 this . registerModules ( this . definition ) ;
502- this . container . register ( "ParentContainer" , { useValue : this } ) ;
503518 }
504519
505520 public get dependencyContainer ( ) : DependencyContainer {
0 commit comments