import { IProxyDiContainer as IProxyDiContainer, ContainerizedDependency as ContainerizedDependency, DependencyClass, ResolveScope } from './types';
import { ContainerSettings as ContainerSettings, DependencyId } from './types';
import { MiddlewareRegistrator, MiddlewareRemover, MiddlewareResolver } from './middleware/middleware.api';
/**
 * A dependency injection container
 */
export declare class ProxyDiContainer implements IProxyDiContainer {
    /**
     * Static counter used to assign unique IDs to containers.
     */
    private static idCounter;
    /**
     * Just unique number identifier for this container, nothing more
     */
    readonly id: number;
    /**
     * Optional parent container from which this container can inherit dependencies.
     */
    readonly parent?: ProxyDiContainer;
    private _children;
    /**
     * Holds dependency instances registered particular in this container.
     */
    private dependencies;
    /**
     * Holds proxies for dependencies registered in parent containers to provide for it dependencies from this container
     */
    private inContextProxies;
    /**
     * Settings that control the behavior of the container and it's children
     */
    readonly settings: Required<ContainerSettings>;
    private middlewareManager;
    /**
     * Creates a new instance of ProxyDiContainer.
     * @param settings Optional container settings to override defaults.
     * @param parent Optional parent container.
     */
    constructor(settings?: ContainerSettings, parent?: ProxyDiContainer);
    registerMiddleware(middleware: MiddlewareRegistrator<any> | MiddlewareRemover<any> | MiddlewareResolver<any>): void;
    removeMiddleware(middleware: MiddlewareRegistrator<any> | MiddlewareRemover<any> | MiddlewareResolver<any>): void;
    /**
     * Registers a dependency in the container. Could register eacher class or instance.
     * In case of class, it will be instantiated without any parameters.
     *
     * @param dependency The dependency instance or dependency class.
     * @param dependencyId The unique identifier for the dependency in this container. Can be a string, symbol, or class constructor (which will be normalized to class name).
     * @throws Error if dependency is already registered and rewriting is not allowed or if invalid dependency (not object) is provided and this it now allowed.
     * @returns Dependency instance, registered in container
     */
    register<T>(DependencyClass: DependencyClass<T>, dependencyId?: DependencyId | DependencyClass<any>): T & ContainerizedDependency;
    register<T>(dependency: T extends new (...args: any[]) => any ? never : T, dependencyId?: DependencyId | DependencyClass<any>): T & ContainerizedDependency;
    /**
     * Checks if a dependency with the given ID is known to the container based on the scope.
     * @param dependencyId The identifier of the dependency. Can be a string, symbol, or class constructor (which will be normalized to class name).
     * @param scope Bitwise enum to control where to search. Defaults to Current | Parent (searches up the hierarchy).
     * @returns True if the dependency is known, false otherwise.
     */
    isKnown(dependencyId: DependencyId | DependencyClass<any>, scope?: ResolveScope): boolean;
    /**
     * Checks if a dependency with the given ID exists in this container only (does not check parents)
     * @param dependencyId The identifier of the dependency. Can be a string, symbol, or class constructor (which will be normalized to class name).
     * @returns True if the dependency exists in this container, false otherwise.
     */
    hasOwn(dependencyId: DependencyId | DependencyClass<any>): boolean;
    /**
     * Resolves a dependency either by its dependency ID or through a class constructor for auto-injectable classes.
     * @param param The dependency ID or class constructor.
     * @param scope Bitwise enum to control where to search. Defaults to Current | Parent (searches up the hierarchy).
     * @returns The resolved dependency instance with container metadata.
     * @throws Error if the dependency cannot be found or is not auto injectable.
     */
    resolve<T>(dependencyId: DependencyId, scope?: ResolveScope): T & ContainerizedDependency;
    resolve<T extends DependencyClass<any>>(SomeClass: T, scope?: ResolveScope): InstanceType<T> & ContainerizedDependency;
    private resolveImpl;
    /**
     * Injects dependencies to the given object based on its defined injections metadata. Does not affect the container.
     * @param injectionsOwner The object to inject dependencies into.
     */
    injectDependenciesTo(injectionsOwner: any): void;
    /**
     * Creates instances for all injectable classes and registers them in this container.
     * @returns This container to allow use along with constructor.
     */
    registerInjectables(): this;
    /**
     * Finalizes dependency injections, prevents further rewriting of dependencies,
     * and recursively bakes injections for child containers.
     */
    bakeInjections(): void;
    /**
     * Creates a child container that inherits settings and dependencies from this container.
     * @returns A new child instance of ProxyDiContainer.
     */
    createChildContainer(): ProxyDiContainer;
    /**
     * Removes a given dependency from the container using either the dependency instance or its ID.
     * @param dependencyOrId The dependency instance or dependency identifier to remove.
     */
    remove(dependencyOrId: DependencyId | ContainerizedDependency): void;
    /**
     * Destroys the container by removing all dependencies,
     * recursively destroying child containers and removing itself from its parent.
     */
    destroy(): void;
    /**
     * Recursively finds a dependency by its ID from this container or its parent.
     * @param dependencyId The identifier of the dependency to find.
     * @returns The dependency if found, otherwise undefined.
     */
    private findDependency;
    /**
     * Normalizes dependency identifier by converting class constructors to their names.
     * @param id The dependency identifier (string, symbol, or class constructor).
     * @returns Normalized dependency identifier (string or symbol).
     */
    private normalizeDependencyId;
    resolveAll<T>(dependencyId: DependencyId, scope?: ResolveScope): (T & ContainerizedDependency)[];
    resolveAll<T extends DependencyClass<any>>(SomeClass: T, scope?: ResolveScope): (InstanceType<T> & ContainerizedDependency)[];
    private recursiveResolveAll;
    /**
     * All direct descendants of this container
     */
    get children(): ProxyDiContainer[];
    /**
     *
     * @param id Unique identifier of container
     * @returns
     */
    getChild(id: number): ProxyDiContainer;
    /**
     * Registers a child container to this container.
     * @param child The child container to add.
     * @throws Error if a child with the same ID already exists.
     */
    private addChild;
    /**
     * Removes a child container by its ID.
     * @param id The identifier of the child container to remove.
     */
    private removeChild;
}
