import { GetReturnType, RegKeyType, KeyType, ClassType } from './utils/types';
import { TypeWithInfo, ClassLoader } from './class/ClassLoader';
export declare class Config {
    /** auto register class self, when class not found. default: false */
    autoRegisterSelf?: boolean;
    /** constructor inject, MUST in TypeScript with emitDecoratorMetadata and use decorator with class, default: true */
    constructorInject?: boolean;
    /** use class loader for autowired default: true */
    useClassLoader?: ClassLoader | boolean;
    /** when implement class not found */
    notFoundHandler?: (type: KeyType) => any;
    /** when have multi implement class */
    conflictHandler?: (type: KeyType, implCls: TypeWithInfo[], sourceCls?: TypeWithInfo) => ClassType | undefined;
    /** create instance hook, return value will replace instance */
    createInstanceHook?: (inst: any, ioc: IocContext) => any;
    /** parent ioc context */
    parentContext?: IocContext;
    /** create new instance in this context when is not exist */
    newInstanceInThisContext?: boolean;
}
export declare const DefaultRegisterOption: RegisterOptions;
export interface RegisterOptions {
    /** default: true */
    singleton?: boolean;
    /** if data a class, auto new a instance.
     *  if data a function, auto run(lazy).
     *  default: true */
    autoNew?: boolean;
}
export interface Store {
    inited: boolean;
    factory: any;
    value: any;
    options: RegisterOptions;
}
/** ioc context */
export declare class IocContext {
    readonly config: Readonly<Config>;
    private static defaultInstance;
    private _classLoader?;
    get classLoader(): ClassLoader;
    private components;
    static get DefaultInstance(): IocContext;
    constructor(config?: Readonly<Config>);
    /**
     * merge config
     * @param config new partial config
     */
    setConfig(config: Partial<Config>): void;
    /**
     * remove instance of key
     * @param keyOrType key
     */
    remove(keyOrType: KeyType): boolean;
    /** clear all */
    clear(): void;
    /**
     * get instance of key
     * @param keyOrType key
     * @param opt
     */
    get<T = undefined, KeyOrType = any>(keyOrType: KeyOrType, opt?: {
        /** always get new instance */
        forceNew?: boolean;
        /** use classLoader */
        useClassLoader?: boolean;
        /** source of invoke cls */
        sourceCls?: ClassType;
        /** source of type */
        sourceType?: KeyOrType;
        /** deep get from parent context, default: true */
        deep?: boolean;
    }): GetReturnType<T, KeyOrType>;
    protected resolveConflict(type: KeyType, classes: TypeWithInfo[], sourceCls?: TypeWithInfo, deep?: boolean): ClassType | undefined;
    private findClassByClassLoader;
    private isInjectableBaseClass;
    /**
     * get instances for key
     * @param keyOrType key (super class or interface, use `@classInfo`)
     * @param opt
     */
    getImports<T = undefined, KeyOrType = any>(keyOrType: KeyOrType, { cache, deep, }?: {
        /** peer cache */
        cache?: boolean;
    } & Partial<Pick<Parameters<IocContext['get']>[1], 'deep'>>): GetReturnType<T, KeyOrType>[];
    /**
     * instance of key in context
     * @param keyOrType key
     * @param deep deep search from parent context
     * @param useClassLoader use classLoader
     */
    has(keyOrType: KeyType, deep?: boolean, useClassLoader?: boolean): boolean;
    replace(keyOrType: KeyType, newData: any, options?: RegisterOptions, registerIfNotExist?: boolean): void;
    /**
     * register key
     * @param data value of key (maybe instance, class, factory function or value)
     * @param key key
     * @param options register option
     */
    register(data: any, key?: RegKeyType, options?: RegisterOptions): void;
    /**
     * complete instance inject
     * @param instance
     * @param opt
     */
    inject(instance: any, opt?: {
        autoRunPostConstruct: boolean;
    }): void;
    runPostConstruct(instance: any): void;
    runPreDestroy(instance: any): void;
    /**
     * create child context, inherit this context
     * @param config
     */
    createChildContext(config?: Config): IocContext;
    /**
     * run preDestroy method of instance
     * @param store instance store
     */
    private preDestroyInstance;
    private newStore;
    private canBeKey;
    private returnValue;
    toJSON(): {
        type: string;
        message: string;
    };
}
export declare class MultiImplementError extends Error {
    constructor(type: ClassType, key: string | symbol);
}
export declare class NotfoundTypeError extends Error {
    constructor(type: any, key: string | symbol);
}
export declare class NoRegistryError extends Error {
    constructor(key: string | symbol);
}
export declare class AlreadyRegistryError extends Error {
    constructor(key: string | symbol);
}
