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 {AbstractFactory} from './factory/AbstractFactory'
|
||||||
import {collect, Collection, globalRegistry, logIfDebugging} from '../util'
|
import {collect, Collection, globalRegistry, logIfDebugging} from '../util'
|
||||||
import {Factory} from './factory/Factory'
|
import {Factory} from './factory/Factory'
|
||||||
@ -66,6 +74,12 @@ export class Container {
|
|||||||
*/
|
*/
|
||||||
protected instances: Collection<InstanceRef> = new Collection<InstanceRef>()
|
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.
|
* Collection of callbacks waiting for a dependency key to be resolved.
|
||||||
* @protected
|
* @protected
|
||||||
@ -110,6 +124,52 @@ export class Container {
|
|||||||
return this
|
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.
|
* Register the given function as a factory within the container.
|
||||||
* @param {string} name - unique name to identify the factory in 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
|
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.
|
* Returns true if the parameter is a static class.
|
||||||
* @param something
|
* @param something
|
||||||
|
Loading…
Reference in New Issue
Block a user