import { Constructable, IDisposable } from './interfaces'; import { ResourceType } from './resource'; import type { IAllResolver, ICallableResolver, IFactoryResolver, ILazyResolver, INewInstanceResolver, IOptionalResolver, IResolvedFactory, IResolvedLazy } from './di.resolvers'; export type ResolveCallback = (handler: IContainer, requestor: IContainer, resolver: IResolver) => T; export interface InterfaceSymbol { $isInterface: boolean; friendlyName?: string; register?(container: IContainer, key?: K): IResolver; toString?(): string; } interface IResolverLike { readonly $isResolver: true; resolve(handler: C, requestor: C): Resolved; getFactory? : IFactory>(container: C): T | null; } export interface IResolver extends IResolverLike, Partial { } export interface IDisposableResolver extends IResolver { dispose(): void; } export interface IRegistration extends IResolver { register(container: IContainer, key?: Key): IResolver; } export type Transformer = (instance: Resolved) => Resolved; export interface IFactory { readonly Type: T; registerTransformer(transformer: Transformer): void; construct(container: IContainer, dynamicDependencies?: unknown[]): Resolved; } export interface IServiceLocator { readonly root: IServiceLocator; has(key: K | Key, searchAncestors: boolean): boolean; get(key: IAllResolver): Resolved[]; get(key: INewInstanceResolver): Resolved; get(key: ILazyResolver): IResolvedLazy; get(key: IOptionalResolver): Resolved | undefined; get(key: IFactoryResolver): IResolvedFactory; get(key: ICallableResolver): Resolved; get(key: IResolver): Resolved; get(key: K): Resolved; get(key: Key): Resolved; get(key: K | Key): Resolved; getAll(key: K, searchAncestors?: boolean): Resolved[]; getAll(key: Key, searchAncestors?: boolean): Resolved[]; getAll(key: K | Key, searchAncestors?: boolean): Resolved[]; } export interface IRegistry { register(container: IContainer, ...params: unknown[]): void | IResolver | IContainer; } export interface IContainer extends IServiceLocator, IDisposable { readonly id: number; readonly root: IContainer; readonly parent: IContainer | null; register(...params: any[]): IContainer; registerResolver>(key: K, resolver: T, isDisposable?: boolean): T; registerTransformer(key: K, transformer: Transformer): boolean; getResolver(key: K | Key, autoRegister?: boolean): IResolver | null; registerFactory(key: Key, factory: IFactory): void; invoke(key: Constructable, dynamicDependencies?: TDeps): T; hasFactory(key: any): boolean; getFactory(key: T): IFactory; createChild(config?: IContainerConfiguration): IContainer; disposeResolvers(): void; deregister(key: Key): void; /** * Register resources from another container, an API for manually registering resources * * This is a semi private API, apps should avoid using it directly */ useResources(container: IContainer): void; find(kind: string, name: string): TResType | null; find(key: string): TResType | null; } export declare class ResolverBuilder { constructor( /** @internal */ _container: IContainer, /** @internal */ _key: Key); instance(value: K): IResolver; singleton(value: Constructable): IResolver; transient(value: Constructable): IResolver; callback(value: ResolveCallback): IResolver; cachedCallback(value: ResolveCallback): IResolver; aliasTo(destinationKey: Key): IResolver; } export type RegisterSelf = { register(container: IContainer): IResolver>; registerInRequestor: boolean; }; export type Key = PropertyKey | object | InterfaceSymbol | Constructable | IResolver; export type Resolved = (K extends InterfaceSymbol ? T : K extends Constructable ? InstanceType : K extends IResolverLike ? T1 extends Constructable ? InstanceType : T1 : K); export type Injectable = Constructable & { inject?: Key[]; }; export type AbstractInjectable = (abstract new (...args: any[]) => T) & { inject?: Key[]; }; export interface IContainerConfiguration { /** * If `true`, `createChild` will inherit the resource resolvers from its parent container * instead of only from the root container. * * Setting this flag will not implicitly perpetuate it in the child container hierarchy. * It must be explicitly set on each call to `createChild`. */ inheritParentResources?: boolean; defaultResolver?(key: Key, handler: IContainer): IResolver; } export declare const inject: (...dependencies: Key[]) => (decorated: unknown, context: DecoratorContext) => void; export declare const DI: { createContainer: (config?: Partial) => IContainer; getDesignParamtypes: (Type: Constructable | Injectable) => readonly Key[] | undefined; getDependencies: (Type: Constructable | Injectable) => Key[]; /** * creates a decorator that also matches an interface and can be used as a {@linkcode Key}. * ```ts * const ILogger = DI.createInterface('Logger'); * container.register(Registration.singleton(ILogger, getSomeLogger())); * const log = container.get(ILogger); * log.info('hello world'); * class Foo { * constructor( @ILogger log: ILogger ) { * log.info('hello world'); * } * } * ``` * you can also build default registrations into your interface. * ```ts * export const ILogger = DI.createInterface('Logger', builder => builder.cachedCallback(LoggerDefault)); * const log = container.get(ILogger); * log.info('hello world'); * class Foo { * constructor( @ILogger log: ILogger ) { * log.info('hello world'); * } * } * ``` * but these default registrations won't work the same with other decorators that take keys, for example * ```ts * export const MyStr = DI.createInterface('MyStr', builder => builder.instance('somestring')); * class Foo { * constructor( @optional(MyStr) public readonly str: string ) { * } * } * container.get(Foo).str; // returns undefined * ``` * to fix this add this line somewhere before you do a `get` * ```ts * container.register(MyStr); * container.get(Foo).str; // returns 'somestring' * ``` * * - @param configureOrName - supply a string to improve error messaging */ createInterface: (configureOrName?: string | ((builder: ResolverBuilder) => IResolver), configuror?: (builder: ResolverBuilder) => IResolver) => InterfaceSymbol; inject: (...dependencies: Key[]) => (decorated: unknown, context: DecoratorContext) => void; /** * Registers the `target` class as a transient dependency; each time the dependency is resolved * a new instance will be created. * * @param target - The class / constructor function to register as transient. * @returns The same class, with a static `register` method that takes a container and returns the appropriate resolver. * * @example ```ts * // On an existing class * class Foo { } * DI.transient(Foo); * * // Inline declaration * const Foo = DI.transient(class { }); * // Foo is now strongly typed with register * Foo.register(container); * ``` */ transient(target: T & Partial>): T & RegisterSelf; /** * Registers the `target` class as a singleton dependency; the class will only be created once. Each * consecutive time the dependency is resolved, the same instance will be returned. * * @param target - The class / constructor function to register as a singleton. * @returns The same class, with a static `register` method that takes a container and returns the appropriate resolver. * @example ```ts * // On an existing class * class Foo { } * DI.singleton(Foo); * * // Inline declaration * const Foo = DI.singleton(class { }); * // Foo is now strongly typed with register * Foo.register(container); * ``` */ singleton(target: T & Partial>, options?: SingletonOptions): T & RegisterSelf; }; export declare const IContainer: InterfaceSymbol; export declare const IServiceLocator: InterfaceSymbol; declare function transientDecorator(target: T & Partial>, context: ClassDecoratorContext): T & RegisterSelf; /** * Registers the decorated class as a transient dependency; each time the dependency is resolved * a new instance will be created. * * @example ```ts * @transient() * class Foo { } * ``` */ export declare function transient(): typeof transientDecorator; /** * Registers the `target` class as a transient dependency; each time the dependency is resolved * a new instance will be created. * * @param target - The class / constructor function to register as transient. * * @example ```ts * @transient() * class Foo { } * ``` */ export declare function transient(target: T & Partial>, context: ClassDecoratorContext): T & RegisterSelf; type SingletonOptions = { scoped: boolean; }; type SingletonDecorator = (target: T & Partial>, context: ClassDecoratorContext) => T & RegisterSelf; /** * Registers the decorated class as a singleton dependency; the class will only be created once. Each * consecutive time the dependency is resolved, the same instance will be returned. * * @example ```ts * @singleton() * class Foo { } * ``` */ export declare function singleton(): SingletonDecorator; export declare function singleton(options?: SingletonOptions): SingletonDecorator; /** * Registers the `target` class as a singleton dependency; the class will only be created once. Each * consecutive time the dependency is resolved, the same instance will be returned. * * @param target - The class / constructor function to register as a singleton. * * @example ```ts * @singleton() * class Foo { } * ``` */ export declare function singleton(target: T & Partial>, context: ClassDecoratorContext): T & RegisterSelf; export declare class InstanceProvider implements IDisposableResolver { get friendlyName(): string | undefined; constructor(name?: string, /** * if not undefined, then this is the value this provider will resolve to * until overridden by explicit prepare call */ instance?: Resolved | null, Type?: Constructable | null); prepare(instance: Resolved): void; get $isResolver(): true; resolve(): Resolved; getFactory : IFactory>(container: IContainer): T | null; dispose(): void; } /** * An implementation of IRegistry that delegates registration to a * separately registered class. The ParameterizedRegistry facilitates the * passing of parameters to the final registry. */ export declare class ParameterizedRegistry implements IRegistry { private readonly key; private readonly params; constructor(key: Key, params: unknown[]); register(container: IContainer): void; } export {}; //# sourceMappingURL=di.d.ts.map