github
DocsBlog
fontcolor_theme
package

API @deepkit/injector

npm install @deepkit/injector

Classes

TransientInjectionTarget [source]
export class TransientInjectionTarget {
    constructor(public readonly token: Token);
}

Class describing where a transient provider will be injected.

Injector [source]
export class Injector {
    constructor(public readonly module: InjectorModule, private buildContext: BuildContext);
    static from(providers: ProviderWithScope[], parent?: Injector): Injector;
    static fromModule(module: InjectorModule): Injector;
    get<T>(token?: ReceiveType<T> | Token<T>, scope?: Scope, optional: boolean = false): ResolveToken<T>;
    set<T>(token: Token<T>, value: any, scope?: Scope): void;
    instantiationCount(token: any, scope?: Scope): number;
    getSetter<T>(token: ReceiveType<T> | Token<T>): Setter<T>;
    getResolver<T>(token?: ReceiveType<T> | Token<T>, label?: string): Resolver<T>;
    clear();
    createSetter<T>(token: ReceiveType<T> | Token<T>, scope?: Scope, label?: string): Setter<T>;
    createResolver<T>(token: ReceiveType<T> | Token<T>, scope?: Scope, label?: string): Resolver<T>;
}

This is the actual dependency injection container. Every module has its own injector.

BuildContext [source]
export class BuildContext {
    static ids: number;
    id: number;
    runtimeContext;
    tagRegistry: TagRegistry;
    providerIndex: BuildProviderIndex;
    /**
     * In the process of preparing providers, each module redirects their
     * global setup calls in this registry.
     */
    globalConfigurationProviderRegistry: ConfigurationProviderRegistry;
}
InjectorContext [source]
export class InjectorContext {
    constructor(public rootModule: InjectorModule, public scope?: Scope);
    /**
     * Returns a resolver for the given token. The returned resolver can
     * be executed to resolve the token. This increases performance in hot paths.
     */
    resolve<T>(module?: InjectorModule, type?: ReceiveType<T> | Token<T>): Resolver<T>;
    setter<T>(module?: InjectorModule, type?: ReceiveType<T> | Token<T>): Setter<T>;
    /**
     * Returns an instance of the given token or type from the injector associated with the specified module.
     *
     * If there is no provider for the token or the provider returns undefined, it returns undefined.
     */
    getOrUndefined<T>(token?: ReceiveType<T> | Token<T>, module?: InjectorModule): ResolveToken<T> | undefined;
    /**
     * Returns an instance of the given token or type from the injector associated with the specified module.
     *
     * If there is no provider for the token or the provider returns undefined, it throws an error.
     */
    get<T>(token?: ReceiveType<T> | Token<T>, module?: InjectorModule): ResolveToken<T>;
    /**
     * Returns the instantiation count of the given token.
     *
     * This is either 0 or 1 for normal providers, and >= 0 for transient or scoped providers.
     */
    instantiationCount(token: Token, module?: InjectorModule, scope?: string): number;
    /**
     * Sets a value for the given token in the injector associated with the specified module.
     *
     * This is useful for scoped providers like HttpRequest that are created dynamically
     * outside the injector container and need to be injected into services.
     */
    set<T>(token: T, value: any, module?: InjectorModule): void;
    static forProviders(providers: ProviderWithScope[]);
    getInjector(module: InjectorModule): Injector;
    getRootInjector(): Injector;
    createChildScope(scope: string): InjectorContext;
}

A InjectorContext is responsible for taking a root InjectorModule and build all Injectors.

It also can create scopes aka a sub InjectorContext with providers from a particular scope.

TagRegistry [source]
export class TagRegistry {
    constructor(public tags: TagRegistryEntry<any>[] = []);
    register(tagProvider: TagProvider<any>, module: InjectorModule);
    resolve<T extends ClassType<Tag<any>>>(tag: T): TagRegistryEntry<InstanceType<T>>[];
}
TagProvider [source]
export class TagProvider<T> {
    constructor(public provider: NormalizedProvider<T>, public tag: Tag<T>);
}
Tag [source]
export class Tag<T, TP extends TagProvider<T> = TagProvider<T>> {
    _: () => T;
    _2: () => TP;
    constructor(public readonly services: T[] = []);
    static provide<P extends ClassType<T> | ValueProvider<T> | ClassProvider<T> | ExistingProvider<T> | FactoryProvider<T>, T extends ReturnType<InstanceType<B>[]>, TP extends ReturnType<InstanceType<B>[]>, B extends ClassType<Tag<any>>>(this: B, provider: P): TP;
}
ConfigurationProviderRegistry [source]
export class ConfigurationProviderRegistry {
    configurations: ConfigureProviderEntry[];
    add(type: Type, call: Function, options: ConfigureProviderOptions);
    mergeInto(registry: ConfigurationProviderRegistry): void;
    get(token: Token): ConfigureProviderEntry[];
}
InjectorModule [source]
export class InjectorModule<C extends InjectorModuleConfig = any> {
    id: number;
    /**
     * Whether this module is for the root module. All its providers are automatically exported and moved to the root level.
     */
    root: boolean;
    /**
     * The built injector. This is set once an Injector for this module has been created.
     */
    injector?: Injector;
    configurationProviderRegistry: ConfigurationProviderRegistry;
    globalConfigurationProviderRegistry: ConfigurationProviderRegistry;
    imports: InjectorModule[];
    configDefinition?: ClassType;
    constructor(public providers: ProviderWithScope[] = [], public parent?: InjectorModule, public config: RemovedUndefined<C> = {} as RemovedUndefined<C>, public exports: ExportType[] = []);
    registerAsChildren(child: InjectorModule): void;
    /**
     * When the module exports providers the importer doesn't want, then `disableExports` disable all exports.
     */
    disableExports(): this;
    /**
     * Makes all the providers, controllers, etc available at the root module, basically exporting everything.
     */
    forRoot(): this;
    /**
     * Reverts the root default setting to false.
     */
    notForRoot(): this;
    unregisterAsChildren(child: InjectorModule): void;
    getChildren(): InjectorModule[];
    setConfigDefinition(config: ClassType): this;
    setParent(parent: InjectorModule): this;
    getParent(): InjectorModule | undefined;
    addExport(...types: (ExportType | ExportType[])[]): this;
    isExported(token: Token): boolean;
    isProvided<T>(token?: Token<T>, type?: ReceiveType<T>): boolean;
    addProvider(...provider: (ProviderWithScope | ProviderWithScope[])[]): this;
    getProviders(): ProviderWithScope[];
    getConfig(): C;
    configure(config: Partial<C>): this;
    getImports(): InjectorModule[];
    getImportedModulesByClass<T extends InjectorModule>(classType: ClassType<T>): T[];
    getImportedModuleByClass<T extends InjectorModule>(classType: ClassType<T>): T;
    getImportedModule<T extends InjectorModule>(module: T): T;
    getExports();
    hasImport<T extends InjectorModule>(moduleClass: ClassType<T>): boolean;
    /**
     * Adds a new import at the end.
     */
    addImport(...modules: InjectorModule<any>[]): this;
    /**
     * Adds a new import at the beginning. Since import order matters, it might be useful to import a module first
     * so its exported providers can be overwritten by imports following this module.
     */
    addImportAtBeginning(...modules: InjectorModule<any>[]): this;
    /**
     * Configures a provider by applying a custom configuration function to its instance.
     * The passed configure function is executed when instance was created.
     * If the provider is in a scope and the scope created multiple instances,
     * the configure function is executed for each instance.
     *
     * The purpose of a provider configuration is to configure the instance, for example
     * call methods on it, set properties, etc.
     *
     * The first parameter of the function is always the instance of the provider that was created.
     * All additional defined parameters will be provided by the dependency injection container.
     *
     * if `options.replace` is true, the returned value of `configure` will
     * replace the instance.
     * if `options.global` is true, the configuration function is applied to all
     * providers in the whole module tree.
     * The `options.order` defines the order of execution of the configuration function.
     * The lower the number, the earlier it is executed.
     */
    configureProvider<T>(configure: (instance: T, ...args: any[]) => any, options: Partial<ConfigureProviderOptions> = {}, type?: ReceiveType<T>): this;
    getOrCreateInjector(buildContext?: BuildContext): Injector;
    getPreparedProvider(token: Token, candidate?: PreparedProvider): PreparedProvider | undefined;
    getSetupProvider(token: Token, candidate?: PreparedProvider): PreparedProvider | undefined;
    resolveToken(token: Token): InjectorModule | undefined;
    getBuiltPreparedProviders(): PreparedProvider[] | undefined;
    /**
     * Prepared the module for an injector tree build.
     *
     *  - Index providers by token so that last known provider is picked (so they can be overwritten).
     *  - Register TagProvider in TagRegistry
     *  - Put TagProvider in providers if not already made.
     *  - Put exports to parent's module with the reference to this, so the dependencies are fetched from the correct module.
     */
    getPreparedProviders(buildContext: BuildContext): PreparedProvider[];
    findRoot(): InjectorModule;
}

Errors

InjectorError [source]
export class InjectorError extends CustomError {
}
CircularDependencyError [source]
export class CircularDependencyError extends InjectorError {
}
ServiceNotFoundError [source]
export class ServiceNotFoundError extends InjectorError {
}
DependenciesUnmetError [source]
export class DependenciesUnmetError extends InjectorError {
}

Functions

tokenLabel [source]
(token: Token): string
resolveToken [source]
(provider: ProviderWithScope): Token
getContainerTokenFromType [source]
(type: Type): ContainerToken
isType [source]
(obj: any): obj is Type
getContainerToken [source]
(type: Token): ContainerToken

Returns a value that can be compared with === to check if two tokens are actually equal even though they are the result of different type expressions.

This is used in the big switch-case statement in the generated code to match DI tokens.

getInjectOptions [source]
(type: Type): Type | undefined

Returns the injector token type if the given type was decorated with Inject<T>.

injectedFunction [source]
<T extends (...args: any) => any>(fn: T, injector: Injector, skipParameters?: number, type?: Type, skipTypeParameters?: number): ((scope?: Scope, ...args: any[]) => ReturnType<T>)
partialFactory [source]
(type: Type | undefined, injector: Injector): (scope?: Scope) => <T>(partial: Partial<{ [K in keyof T]: T[K]; }>) => T
provide [source]
<T>(provider?: (ProviderBase & ProviderScope & ({ useValue?: T; } | { useClass: ClassType; } | { useExisting: any; } | { useFactory: (...args: any[]) => T | undefined; })) | ClassType | ((...args: any[]) => T), type?: ReceiveType<T>): NormalizedProvider
isScopedProvider [source]
(obj: any): obj is ProviderProvide & ProviderScope
isValueProvider [source]
(obj: any): obj is ValueProvider<any>
isClassProvider [source]
(obj: any): obj is ClassProvider<any>
isExistingProvider [source]
(obj: any): obj is ExistingProvider<any>
isFactoryProvider [source]
(obj: any): obj is FactoryProvider<any>
isInjectionProvider [source]
(obj: any): obj is Provider<any>
isTransient [source]
(provider: ProviderWithScope): boolean
getProviders [source]
(providers: ProviderWithScope[], requestScope: "module" | "session" | "request" | string): Provider<any>[]
findModuleForConfig [source]
(config: ClassType, modules: InjectorModule[]): { module: InjectorModule; path: string; } | undefined
isProvided [source]
<T>(providers: ProviderWithScope[], token: Token<T>): boolean
getScope [source]
(provider: ProviderWithScope): string
nominalCompatibility [source]
(token: Type, provider: Type): number

Checks if given type is nominally compatible with the given interface.

0 means not compatible, 1 means exactly compatible, n>1 means compatible but not exactly. The higher the number the further away the compatibility is (the inheritance chain).

wrapComponent [source]
<T extends Function>(fn: T & { __injected?: any; }, container: InjectorContext): any
provideServices [source]
<T extends Function>(fn: T, providers: ProviderWithScope[]): T
ServiceContainer [source]
(props: { providers?: ProviderWithScope[]; module?: InjectorModule; state?: ClassType; children?: any; }): any

Wraps the given component with a new injector context.

Types

Scope [source]
interface Scope {
    name: string;
}
ResolveToken [source]
type ResolveToken<T> = T extends ClassType<infer R> ? R : T extends AbstractClassType<infer R> ? R : T;
ContainerToken [source]
type ContainerToken = symbol | number | bigint | boolean | string | AbstractClassType<unknown> | Function;
PartialFactory [source]
type PartialFactory<C> = (args: Partial<{ [K in keyof C]: C[K] }>) => C;

A factory function for some class. All properties that are not provided will be resolved using the injector that was used to create the factory.

Resolver [source]
interface Resolver<T> {
    (scope: Scope | undefined, optional: true): T | undefined;

    (scope?: Scope, optional?: boolean): T;
}
Setter [source]
type Setter<T> = (value: T, scope?: Scope, optional?: boolean) => void;
ProviderBase [source]
interface ProviderBase {
    /**
     * Per default all instances are singleton (scoped to its scope). Enabling transient makes the
     * Injector create always a new instance for every consumer.
     */
    transient?: true;
}
ProviderScope [source]
interface ProviderScope {
    scope?: 'rpc' | 'http' | 'cli' | string;
}
Token [source]
type Token<T = unknown> = symbol | number | bigint | boolean | string | AbstractClassType<T> | Type | TagProvider<T> | Function | T;
ValueProvider [source]
interface ValueProvider<T> extends ProviderBase {
    /**
     * An injection token.
     */
    provide: Token<T>;

    /**
     * The value to inject.
     */
    useValue: T;
}
ClassProvider [source]
interface ClassProvider<T> extends ProviderBase {
    /**
     * An injection token.
     */
    provide: Token<T>;

    /**
     * Class to instantiate for the `token`.
     */
    useClass?: ClassType<T>;
}
ExistingProvider [source]
interface ExistingProvider<T> extends ProviderBase {
    /**
     * An injection token.
     */
    provide: Token<T>;

    /**
     * Existing `token` to return. (equivalent to `injector.get(useExisting)`)
     */
    useExisting: ClassType<T>;
}
FactoryProvider [source]
interface FactoryProvider<T> extends ProviderBase {
    /**
     * An injection token.
     */
    provide: Token<T>;

    /**
     * A function to invoke to create a value for this `token`.
     */
    useFactory: (...args: any[]) => T | undefined;
}
Provider [source]
type Provider<T = any> = AbstractClassType | ValueProvider<T> | ClassProvider<T> | ExistingProvider<T> | FactoryProvider<T> | TagProvider<T>;
ProviderProvide [source]
type ProviderProvide<T = any> = ValueProvider<T> | ClassProvider<T> | ExistingProvider<T> | FactoryProvider<T>;
NormalizedProvider [source]
type NormalizedProvider<T = any> = ProviderProvide<T> & ProviderScope;
ProviderWithScope [source]
type ProviderWithScope<T = any> = AbstractClassType | (ProviderProvide<T> & ProviderScope) | TagProvider<any>;
ConfigureProviderOptions [source]
interface ConfigureProviderOptions {
    /**
     * If there are several registered configuration functions for the same token,
     * they are executed in order of their `order` value ascending. The default is 0.
     * The lower the number, the earlier it is executed.
     */
    order: number;

    /**
     * Replaces the instance with the value returned by the configuration function.
     */
    replace: boolean;

    /**
     * Per default only providers in the same module are configured.
     * If you want to configure providers of all modules, set this to true.
     */
    global: boolean;
}
ConfigureProviderEntry [source]
interface ConfigureProviderEntry {
    type: Type;
    options: ConfigureProviderOptions;
    call: Function;
}
PreparedProvider [source]
interface PreparedProvider {
    token: Token;

    /**
     * The modules from which dependencies can be resolved. The first item is always the module from which this provider was declared.
     *
     * This is per default the module in which the provider was declared,
     * but if the provider was moved (by exporting), then if
     *   a) the parent had this provider already, then this array has additionally the one from which the provider was exported.
     *   b) the parent had no provider of that token, then this array is just the module from which the provider was exported.
     *
     * This is important otherwise exported provider won't have access in their dependencies to their original (encapsulated) injector.
     */
    modules: InjectorModule[];

    /**
     * A token can have multiple providers, for each scope its own entry.
     * Each scoped provider can only exist once.
     */
    providers: NormalizedProvider[];

    /**
     * When this provider was exported to another module and thus is actually instantiated in another module, then this is set.
     * This is necessary to tell the module who declared this provider to not instantiate it, but redirects resolve requests
     * to `resolveFrom` instead.
     */
    resolveFrom?: InjectorModule;
}
ExportType [source]
type ExportType = Token | InjectorModule;
InjectorModuleConfig [source]
type InjectorModuleConfig = { [name: string]: any } | undefined;