2021-06-03 03:36:25 +00:00
|
|
|
export const DEPENDENCY_KEYS_METADATA_KEY = 'extollo:di:dependencies:ctor'
|
|
|
|
export const DEPENDENCY_KEYS_PROPERTY_METADATA_KEY = 'extollo:di:dependencies:properties'
|
|
|
|
export const DEPENDENCY_KEYS_SERVICE_TYPE_KEY = 'extollo:di:service_type'
|
2021-06-02 01:59:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface that designates a particular value as able to be constructed.
|
|
|
|
*/
|
|
|
|
export interface Instantiable<T> {
|
|
|
|
new(...args: any[]): T
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if the given value is instantiable.
|
|
|
|
* @param what
|
|
|
|
*/
|
2021-06-03 03:36:25 +00:00
|
|
|
export function isInstantiable<T>(what: unknown): what is Instantiable<T> {
|
|
|
|
return (
|
|
|
|
Boolean(what)
|
|
|
|
&& (typeof what === 'object' || typeof what === 'function')
|
|
|
|
&& (what !== null)
|
|
|
|
&& 'constructor' in what
|
|
|
|
&& typeof what.constructor === 'function'
|
|
|
|
)
|
2021-06-02 01:59:40 +00:00
|
|
|
}
|
|
|
|
|
2021-09-21 18:42:06 +00:00
|
|
|
/**
|
|
|
|
* Returns true if the given value is instantiable and, once instantiated,
|
|
|
|
* will create an instance of the given static class.
|
|
|
|
* @param what
|
|
|
|
* @param type
|
|
|
|
*/
|
|
|
|
export function isInstantiableOf<T>(what: unknown, type: StaticClass<T, any>): what is Instantiable<T> {
|
|
|
|
return isInstantiable(what) && what.prototype instanceof type
|
|
|
|
}
|
|
|
|
|
2021-06-02 01:59:40 +00:00
|
|
|
/**
|
|
|
|
* Type that identifies a value as a static class, even if it is not instantiable.
|
|
|
|
*/
|
2022-04-04 19:45:45 +00:00
|
|
|
export type StaticClass<T, T2, TCtorParams extends any[] = any[]> = Function & {prototype: T} & { new (...args: TCtorParams) : T } & T2 // eslint-disable-line @typescript-eslint/ban-types
|
2021-06-02 01:59:40 +00:00
|
|
|
|
2021-11-26 20:31:18 +00:00
|
|
|
/**
|
|
|
|
* Type that identifies a value as a static class that instantiates to itself
|
|
|
|
*/
|
|
|
|
export type StaticInstantiable<T> = StaticClass<T, Instantiable<T>>
|
|
|
|
|
2021-06-02 01:59:40 +00:00
|
|
|
/**
|
|
|
|
* Returns true if the parameter is a static class.
|
|
|
|
* @param something
|
|
|
|
*/
|
2021-06-03 03:36:25 +00:00
|
|
|
export function isStaticClass<T, T2>(something: unknown): something is StaticClass<T, T2> {
|
2021-06-02 01:59:40 +00:00
|
|
|
return typeof something === 'function' && typeof something.prototype !== 'undefined'
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Type used to represent a value that can identify a factory in the container.
|
|
|
|
*/
|
|
|
|
export type DependencyKey = Instantiable<any> | StaticClass<any, any> | string
|
|
|
|
|
2021-09-21 18:42:06 +00:00
|
|
|
/**
|
|
|
|
* A DependencyKey, but typed
|
|
|
|
*/
|
|
|
|
export type TypedDependencyKey<T> = Instantiable<T> | StaticClass<T, any> | string
|
|
|
|
|
2021-06-02 01:59:40 +00:00
|
|
|
/**
|
|
|
|
* Interface used to store dependency requirements by their place in the injectable
|
|
|
|
* target's parameters.
|
|
|
|
*/
|
|
|
|
export interface DependencyRequirement {
|
|
|
|
paramIndex: number,
|
|
|
|
key: DependencyKey,
|
|
|
|
overridden: boolean,
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface used to store dependency requirements by the class property they should
|
|
|
|
* be injected into.
|
|
|
|
*/
|
|
|
|
export interface PropertyDependency {
|
|
|
|
key: DependencyKey,
|
|
|
|
property: string | symbol,
|
2021-09-21 18:42:06 +00:00
|
|
|
debug?: boolean,
|
2021-06-02 01:59:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface used to keep track of singleton factory values, by their dependency key.
|
|
|
|
*/
|
|
|
|
export interface InstanceRef {
|
|
|
|
key: DependencyKey,
|
|
|
|
value: any,
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Interface used to keep track of the injection type of a class.
|
|
|
|
*/
|
|
|
|
export interface InjectionType {
|
|
|
|
type: 'named' | 'singleton',
|
|
|
|
name?: string,
|
|
|
|
}
|