export declare enum DependencyScope {
    Singleton = 0,
    Transient = 1
}
export type Provider<T> = new (...args: any[]) => T;
export interface RegisteredDependency<T> {
    key: symbol;
    provider: Provider<T>;
    scope: DependencyScope;
}
/**
 * Mark a class as injectable and register it to DependencyInjection.
 *
 * @param key When not supplied, the class itself will be the key
 */
export declare const Injectable: (scope?: DependencyScope, key?: string | symbol) => (constructor: Provider<any>) => void;
/**
 * Dependency injection singleton.
 *
 * Can be used to register or get dependency.
 */
declare class DependencyInjection {
    private static providers;
    private static singletonCache;
    private constructor();
    /**
     * Register a dependency provider.
     */
    static registerProvider<T>(key: string | symbol, provider: Provider<T>, scope?: DependencyScope): void;
    /**
     * Get a dependency.
     *
     * If the dependency provider's scope is transient, this will create a new instance and returns it.
     * If the dependency provider's scope is singleton, this will returns the already cached instance.
     */
    static get<T>(key: string | symbol | Provider<T>): T;
    /**
     * Resolve dependency's symbol key based on class/symbol/string key.
     */
    static resolveKey<T>(key: string | symbol | Provider<T>): symbol;
}
export default DependencyInjection;
