import { ClassType, TargetType } from '../base/type';
import { RequestContext } from '../context/request.context';
import { IocLoadOptions } from './ioc.load.options';
/** 基于此类的 `ScopeEnum.Request` 型自动注入对象，在释放时会触发 `onFree` 事件 */
export declare abstract class BaseProvider {
    /** 对象释放时自动调用 */
    abstract onFree(): void;
}
/** 作用域 */
export declare enum ScopeEnum {
    /** 单例，全局唯一（进程级别） */
    Singleton = 0,
    /** **默认**，请求 (Context) 作用域， Context 生命周期上唯一，Context 释放时立即销毁 (如果实例化时没有指定 Context，则和 `Prototype` 一样 ) */
    Request = 1,
    /** 原型作用域，每次调用都会重复创建一个新的对象 */
    Prototype = 2
}
/** TS 设计期类型信息 */
export declare class TSDesignType {
    name: string;
    isBaseType: boolean;
    /** 原始的设计期类型信息 */
    origin: any;
}
/** 基类标识，主要功能是留下构造函数参数信息 */
export declare function BaseClass(): (target: any) => void;
/**
 * 提供者标识, 在 Service、Model 类型上使用, 如果实现自动注入，构造函数应无参数或只有Context参数
 * @param identifier 标识符，如果不指定，默认为类名
 * @param scope 作用域, 默认为 `ScopeEnum.Request`
 */
export declare function Provide(identifier?: string, scope?: ScopeEnum): (target: any) => void;
/**
 * 标识 Service 提供者
 * @param identifier 标识符，如果不指定，默认为类名
 * @param scope 作用域, 默认为 `ScopeEnum.Request`
 */
export declare const Service: typeof Provide;
/**
 * 标识 Wrapper 提供者
 * @param identifier 标识符，如果不指定，默认为类名
 * @param scope 作用域, 默认为 `ScopeEnum.Request`
 */
export declare const Wrapper: typeof Provide;
/**
 * 路由配置标识装饰器
 * @param baseUrl 基础路径，使用 "/" 开头
 * @param logPackage 是否输出 api 日志
 * @returns
 */
export declare function Route(baseUrl?: string, logPackage?: boolean): (target: any) => void;
/** 注入参数类型 */
export declare type InjectArgsType = ClassType<any> | InjectClassParam | string | number | boolean | any[] | Set<any> | Map<any, any> | Record<string, any> | void | null | undefined;
/** 注入Class参数 */
export declare class InjectClassParam {
    /** 类型 */
    type: ClassType<any>;
    /** 参数列表 */
    args?: InjectArgsType[];
}
/** 自动注入选项 */
export interface InjectOptions {
    /** 自动注入时是否必须成功, 默认为 `true`，如果注入失败时会抛出异常。设为 `false` 时，实例化失败时会返回 `undefined` */
    must?: boolean;
    /** （可选）注入失败时的错误信息， 默认会提示 xxx 参数注入失败 */
    errMsg?: string;
    /**
     * （可选）实例化注入对象时的参数列表
     * @description 如果参数是一个 `ClassType` 时，直接使用类名，如果类实例化时需要除 `Context` 之外的参数， 则使用 `{ type: ClassType<any>, args: any[] }` 的方式进行定义
     */
    args?: InjectArgsType[];
}
/**
 * 自动注入装饰器，支持构造器和属性注入，支持注入对象和函数（参考 `injectWrapper`）
 * @param identifier 标识符，如果不指定，默认为参数名称
 * @param options 可选，注入选项设置。用于指定实例化参数等信息
 * @returns
 */
export declare function inject(identifier?: string, options?: InjectOptions): (target: any, targetKey: string, index?: number | undefined) => void;
/**
 * 自动注入函数 Wrapper
 */
export declare function injectWrapper(wrapperInfo: Array<{
    id: string;
    provider: (context: RequestContext, ...args: any | undefined) => any;
}>): void;
/** 配置信息来源 */
export declare enum ConfigScope {
    app = 0,
    config = 1,
    server = 2,
    context = 3
}
/**
 * 自动配置信息注入装饰器, 只支持属性注入
 * @param path 配置信息的名称完整路径，默认使用字段名称，不区分大小写
 * @param scope 配置信息来源, 默认 `ConfigScope.config`。如果是数组，则以先后顺序作为优先级获取
 * @param defaultValue 默认值
 * @description Path 示例："ossConfig"、"ossConfig.region"、"apiBaseUrl"
 * @returns
 */
export declare function config(path?: string, scope?: ConfigScope | ConfigScope[], defaultValue?: any): (target: any, targetKey: string) => void;
declare class InjectConfigItem {
    path?: string;
    scope?: ConfigScope | ConfigScope[];
    targetKey: string;
    target: any;
    defaultValue?: any;
}
declare class ContainerItem<T = ClassType<any> | Function> {
    classType: T;
    scope: ScopeEnum;
    uuid: string;
    constructorArgs: Array<InjectData>;
}
declare class InjectData {
    readonly identifier: string;
    readonly type: number;
    /**
     *
     * @param identifier 标识符
     * @param type 类型：0 构造器，1 属性, 2 非注入的占位参数
     */
    constructor(identifier: string, type: number);
    targetKey: string;
    target: any;
    args?: any;
    errMsg?: string;
    /** 是否必须注入成功，否则抛出异常，默认为 `true` */
    must: boolean;
    /** 参数位置 */
    index?: number;
}
/**
 * IOC 控制反转容器
 */
export declare class IocContainer {
    /** 配置信息, 自动注入配置时作为数据源 */
    static config?: any;
    /** 全局容器 */
    private static readonly container;
    private static readonly provideMap;
    private static readonly provideUuidMap;
    /** 单例列表 */
    private static readonly singletonList;
    /** 手动注册的对象或函数 */
    private static readonly injectObjectList;
    /** Context容器 */
    private static readonly contextContainer;
    /** 注入映射 */
    private static readonly injectMap;
    private static readonly injectIdMap;
    /** 配置注入映射 */
    private static readonly injectConfigIdMap;
    /** 缓存类型需要注入的属性列表 */
    private static readonly injectClsMap;
    private static creating;
    /** 获取类型定义数据 */
    static getDefinition<T>(identifier: string | ClassType<T>): [ContainerItem | undefined, string];
    /**
     * 获取接口实现类
     * @param identifier 标识符
     * @param context 上下文对象
     * @param args 可选，实例化实现类的参数列表，需要视具休的实现类实例化参数而定
     * @returns
     */
    static get<T>(identifier: string | ClassType<T>, context?: RequestContext, ...args: any | undefined): T | undefined;
    /**
     * 获取配置信息
     * @param path 配置信息的名称完整路径，默认使用字段名称，不区分大小写
     * @param scope 配置信息来源, 默认 `ConfigScope.config`。如果是数组，则以先后顺序作为优先级获取
     * @param defaultValue 默认值
     * @param context 上下文对象
     */
    static getConfig<T>(path: string, scope?: ConfigScope | ConfigScope[], context?: RequestContext, defaultValue?: T): T | undefined;
    private static getData;
    private static getObject;
    /** 释放上下文容器 */
    static destroy(context?: any): void;
    /** 实例化对象 */
    static createObject<T>(context: RequestContext | undefined, definition: ContainerItem<ClassType<any>>, ...args: any | undefined): T;
    private static getInstanceInjectCache;
    /**
     * 注入属性
     * @param instance 对象实例
     */
    static resolveInject(context: RequestContext | undefined, instance: Record<string, any>, target: TargetType<any>): void;
    /**
     * 注入配置属性
     * @param instance 对象实例
     */
    static resolveInjectConfigFiled(context: RequestContext | undefined, instance: Record<string, any>, target: TargetType<any>): void;
    private static getConfigData;
    /** 生成一个匿名对象的类类型, 使用 `new` 的时候，返回这个对象本身 */
    static getUnknowClassType<T>(obj: T, className?: string): ClassType<T>;
    /** 获取指定类的构造参数 */
    static getClassConstructorArgs(context: RequestContext | undefined, target: ClassType<any>, definition?: ContainerItem<ClassType<any>>): any[] | undefined;
    /** 获取构造函数需要注入的参数列表 */
    private static getConstructorInject;
    /** 获取类需要注入的参数列表 */
    private static getClassInject;
    /**
     * 获取指定类的注入数据列表
     * @param className 类名称
     * @param type 注入数据类型 0 构造函数 1 属性
     * @returns
     */
    private static getInjectList;
    private static compareAndSetCreateStatus;
    /**
     * 绑定对象定义
     * @param identifier 标识名称, 不区分大小写
     * @param scope 作用域
     * @param module 实现类
     */
    static bind(module: ClassType<any>, identifier?: string, scope?: ScopeEnum): void;
    /**
     * 绑定动态 Wrapper 函数定义
     * @param identifier 标识名称, 不区分大小写
     * @param provider 实现函数
     * @description `
     * export function xxx(context: RequestContext): any {
     *  return () => { return data; }
     * }`
     */
    static bindInjectWrapper(provider: (context: RequestContext, ...args: any | undefined) => any, identifier: string): void;
    /** 注入已有对象 */
    static registerObject(identifier: string, obj: any): void;
    static _saveInjectData(data: InjectData): void;
    static _saveConfigInjectData(data: InjectConfigItem): void;
    /** 查找接口名称的实现类 */
    private static findImplementClass;
    static getParamTypes(classType: ClassType<any>): any[] | undefined;
    static getParamNames(func: any): string[];
    static isNullOrUndefined(value: any): boolean;
    static transformTypeFromTSDesign(designFn: any): TSDesignType;
    static getPropertyType(target: any, propertyKey: string | symbol): TSDesignType;
    private static fnBody;
    static isContext(fn: any): boolean;
    static isClass(fn: any): boolean;
    static isFunction(value: any): boolean;
    static isObject(value: any): boolean;
    static isProvide(target: ClassType<any>): boolean;
    static isTypeScriptEnvironment(): boolean;
    static isRouteConfig(target: ClassType<any>): boolean;
    static getRouteConfig(target: ClassType<any>): {
        basePath: string;
        logPackage?: boolean;
    } | undefined;
    static getProviderUUId(module: ClassType<any>): string | undefined;
    static getProviderId(module: ClassType<any>): string | undefined;
    static generateRandomId(): string;
    /** 获取项目自动加载时的根目录 */
    static getBaseDir(devPath?: string, distPath?: string): string;
    /** 自动扫描，加载模块 */
    static loadDirectory(opts: IocLoadOptions, onBindClass?: (exports: any, filePath?: string) => void): void;
}
export {};
