|
|
|
@ -8,7 +8,16 @@ import {
|
|
|
|
|
TypedDependencyKey,
|
|
|
|
|
} from './types'
|
|
|
|
|
import {AbstractFactory} from './factory/AbstractFactory'
|
|
|
|
|
import {Awaitable, collect, Collection, ErrorWithContext, globalRegistry, hasOwnProperty, logIfDebugging} from '../util'
|
|
|
|
|
import {
|
|
|
|
|
Awaitable,
|
|
|
|
|
collect,
|
|
|
|
|
Collection,
|
|
|
|
|
ErrorWithContext,
|
|
|
|
|
globalRegistry,
|
|
|
|
|
hasOwnProperty,
|
|
|
|
|
logIfDebugging,
|
|
|
|
|
withErrorContext,
|
|
|
|
|
} from '../util'
|
|
|
|
|
import {Factory} from './factory/Factory'
|
|
|
|
|
import {DuplicateFactoryKeyError} from './error/DuplicateFactoryKeyError'
|
|
|
|
|
import {ClosureFactory} from './factory/ClosureFactory'
|
|
|
|
@ -376,7 +385,7 @@ export class Container {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Resolve the dependency key. If a singleton value for that key already exists in this container,
|
|
|
|
|
* return that value. Otherwise, use the factory an given parameters to produce and return the value.
|
|
|
|
|
* return that value. Otherwise, use the factory and given parameters to produce and return the value.
|
|
|
|
|
* @param {DependencyKey} key
|
|
|
|
|
* @param {...any} parameters
|
|
|
|
|
*/
|
|
|
|
@ -432,11 +441,16 @@ export class Container {
|
|
|
|
|
// Create the dependencies for the factory
|
|
|
|
|
const keys = factory.getDependencyKeys().filter(req => this.hasKey(req.key))
|
|
|
|
|
const dependencies = keys.map<ResolvedDependency>(req => {
|
|
|
|
|
return withErrorContext(() => {
|
|
|
|
|
return {
|
|
|
|
|
paramIndex: req.paramIndex,
|
|
|
|
|
key: req.key,
|
|
|
|
|
resolved: this.resolveAndCreate(req.key),
|
|
|
|
|
}
|
|
|
|
|
}, {
|
|
|
|
|
producingToken: factory.getTokenName(),
|
|
|
|
|
constructorDependency: req,
|
|
|
|
|
})
|
|
|
|
|
}).sortBy('paramIndex')
|
|
|
|
|
|
|
|
|
|
// Build the arguments for the factory, using dependencies in the
|
|
|
|
@ -460,7 +474,12 @@ export class Container {
|
|
|
|
|
factory.getInjectedProperties().each(dependency => {
|
|
|
|
|
logIfDebugging('extollo.di.injector', 'Resolving injected dependency:', dependency)
|
|
|
|
|
if ( dependency.key && inst ) {
|
|
|
|
|
withErrorContext(() => {
|
|
|
|
|
(inst as any)[dependency.property] = this.resolveAndCreate(dependency.key)
|
|
|
|
|
}, {
|
|
|
|
|
producingToken: factory.getTokenName(),
|
|
|
|
|
propertyDependency: dependency,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
@ -499,15 +518,23 @@ export class Container {
|
|
|
|
|
this.checkForMakeCycles()
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const result = withErrorContext(() => {
|
|
|
|
|
if (this.hasKey(target)) {
|
|
|
|
|
const realized = this.resolveAndCreate(target, ...parameters)
|
|
|
|
|
Container.makeStack.pop()
|
|
|
|
|
Container.makeStack?.pop()
|
|
|
|
|
return realized
|
|
|
|
|
} else if (typeof target !== 'string' && isInstantiable(target)) {
|
|
|
|
|
const realized = this.produceFactory(new Factory(target), parameters)
|
|
|
|
|
Container.makeStack.pop()
|
|
|
|
|
Container.makeStack?.pop()
|
|
|
|
|
return realized
|
|
|
|
|
}
|
|
|
|
|
}, {
|
|
|
|
|
makeStack: Container.makeStack,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if ( result ) {
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
} catch (e: unknown) {
|
|
|
|
|
Container.makeStack.pop()
|
|
|
|
|
throw e
|
|
|
|
|