DI: add logic for static class overrides
This commit is contained in:
parent
6fc901b3ec
commit
bf4a675faa
@ -1,4 +1,12 @@
|
||||
import {DependencyKey, InstanceRef, Instantiable, isInstantiable, StaticClass, TypedDependencyKey} from './types'
|
||||
import {
|
||||
DependencyKey,
|
||||
InstanceRef,
|
||||
Instantiable,
|
||||
isInstantiable,
|
||||
StaticClass,
|
||||
StaticInstantiable,
|
||||
TypedDependencyKey,
|
||||
} from './types'
|
||||
import {AbstractFactory} from './factory/AbstractFactory'
|
||||
import {collect, Collection, globalRegistry, logIfDebugging} from '../util'
|
||||
import {Factory} from './factory/Factory'
|
||||
@ -66,6 +74,12 @@ export class Container {
|
||||
*/
|
||||
protected instances: Collection<InstanceRef> = new Collection<InstanceRef>()
|
||||
|
||||
/**
|
||||
* Collection of static-class overrides registered with this container.
|
||||
* @protected
|
||||
*/
|
||||
protected staticOverrides: Collection<{ base: StaticInstantiable<any>, override: StaticInstantiable<any> }> = new Collection<{base: StaticInstantiable<any>; override: StaticInstantiable<any>}>()
|
||||
|
||||
/**
|
||||
* Collection of callbacks waiting for a dependency key to be resolved.
|
||||
* @protected
|
||||
@ -110,6 +124,52 @@ export class Container {
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a static class as an override of some base class.
|
||||
* @param base
|
||||
* @param override
|
||||
*/
|
||||
registerStaticOverride<T>(base: StaticInstantiable<T>, override: StaticInstantiable<T>): this {
|
||||
if ( this.hasStaticOverride(base) ) {
|
||||
throw new DuplicateFactoryKeyError(base)
|
||||
}
|
||||
|
||||
this.staticOverrides.push({
|
||||
base,
|
||||
override,
|
||||
})
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/** Returns true if a static override exists for the given base class. */
|
||||
hasStaticOverride<T>(base: StaticInstantiable<T>): boolean {
|
||||
return this.staticOverrides.where('base', '=', base).isNotEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the static class overriding the base class.
|
||||
* @param base
|
||||
*/
|
||||
getStaticOverride<T>(base: StaticInstantiable<T>): StaticInstantiable<T> {
|
||||
const override = this.staticOverrides.firstWhere('base', '=', base)
|
||||
if ( override ) {
|
||||
return override.override
|
||||
}
|
||||
|
||||
return base
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registered instance of the static override of a given class.
|
||||
* @param base
|
||||
* @param parameters
|
||||
*/
|
||||
makeByStaticOverride<T>(base: StaticInstantiable<T>, ...parameters: any[]): T {
|
||||
const key = this.getStaticOverride(base)
|
||||
return this.make(key, ...parameters)
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given function as a factory within the container.
|
||||
* @param {string} name - unique name to identify the factory in the container
|
||||
|
@ -38,6 +38,11 @@ export function isInstantiableOf<T>(what: unknown, type: StaticClass<T, any>): w
|
||||
*/
|
||||
export type StaticClass<T, T2> = Function & {prototype: T} & T2 // eslint-disable-line @typescript-eslint/ban-types
|
||||
|
||||
/**
|
||||
* Type that identifies a value as a static class that instantiates to itself
|
||||
*/
|
||||
export type StaticInstantiable<T> = StaticClass<T, Instantiable<T>>
|
||||
|
||||
/**
|
||||
* Returns true if the parameter is a static class.
|
||||
* @param something
|
||||
|
Loading…
Reference in New Issue
Block a user