import { AbstractConstructor, Constructor } from 'type-fest';
import { BindingState } from './BindingState';
import { Entry, EntryConstructor, EntryOptions } from './Entry';
import { DecoratedOCAliasMap, OCAliasMap } from '../config/bind';
import { Namespace } from '../Namespace';
type WithDependencies = {
    readonly $dependencies: Dependencies;
};
export type OCInjectable<T> = (Constructor<T> & WithDependencies) | (AbstractConstructor<T> & Partial<WithDependencies>) | (Function & {
    prototype: T;
} & Partial<WithDependencies>);
export type Dependencies<T = any> = Dependency<T>[];
export type Dependency<T> = keyof DecoratedOCAliasMap | OCInjectable<T> | [
    OCInjectable<T>,
    {
        optional: boolean;
    }
];
export type OCInstanceConstrain<T = any> = keyof DecoratedOCAliasMap | Constructor<T> | AbstractConstructor<T> | [AbstractConstructor<T> | Constructor<T>, {
    optional: true;
}];
export type OCInstance<T extends OCInstanceConstrain> = T extends keyof DecoratedOCAliasMap ? DecoratedOCAliasMap[T] : T extends AbstractConstructor<any> | Constructor<any> ? InstanceType<T> : T extends [
    AbstractConstructor<any> | Constructor<any>,
    {
        optional: true;
    }
] ? InstanceType<T[0]> | null : T;
/**
 * The Object Container is an enhanced dependency injector with support for
 * aliases and constants, and allowing to reference classes in the application
 * namespace by specifying their fully qualified names.
 */
export declare class ObjectContainer {
    #private;
    /**
     * The current binding state.
     *
     * The {@link setBindingState()} method may be called for changing
     * object container binding state only by the bootstrap script.
     */
    private _bindingState?;
    /**
     * The current plugin binding to OC.
     *
     * The {@link setBindingState()} method may be called for changing
     * object container binding state only by the bootstrap script.
     */
    private _bindingPlugin?;
    private _entries;
    /**
     * The namespace container, used to access classes and values using
     * their fully qualified names.
     */
    private _namespace;
    /**
     * Initializes the object container.
     *
     * @param namespace The namespace container, used to
     *        access classes and values using their fully qualified names.
     */
    constructor(namespace: Namespace);
    /**
     * Binds the specified class or factory function and dependencies to the
     * specified alias. Binding a class or factory function to an alias allows
     * the class or function to be specified as a dependency by specifying the
     * alias and creating new instances by referring to the class or function
     * by the alias.
     *
     * Also note that the same class or function may be bound to several
     * aliases and each may use different dependencies.
     *
     * The alias will use the default dependencies bound for the class if no
     * dependencies are provided.
     *
     * @param name Alias name.
     * @param classConstructor The
     *        class constructor or a factory function.
     * @param dependencies The dependencies to pass into the
     *        constructor or factory function.
     * @return This object container.
     */
    bind<T extends keyof OCAliasMap, C>(name: T, classConstructor: OCInjectable<C>, dependencies?: any[]): this;
    /**
     * Defines a new constant registered with this object container. Note that
     * this is the only way of passing `string` values to constructors
     * because the object container treats strings as class, interface, alias
     * or constant names.
     *
     * @param name The constant name.
     * @param value The constant value.
     * @return This object container.
     */
    constant<T extends keyof OCAliasMap, V>(name: T, value: V): this;
    /**
     * Configures the object loader with the specified default dependencies for
     * the specified class.
     *
     * New instances of the class created by this object container will receive
     * the provided dependencies into constructor unless custom dependencies
     * are provided.
     *
     * @param classConstructor The class constructor.
     * @param dependencies The dependencies to pass into the
     *        constructor function.
     * @return This object container.
     */
    inject<T>(classConstructor: Constructor<T>, dependencies: any[]): this;
    /**
     * Configures the default implementation of the specified interface to use
     * when an implementation provider of the specified interface is requested
     * from this object container.
     *
     * The implementation constructor will obtain the provided default
     * dependencies or the dependencies provided to the {@link create()}
     * method.
     *
     * @param interfaceConstructor The constructor
     *        of the interface representing the service.
     * @param implementationConstructor
     *        The constructor of the class implementing the service interface.
     * @param dependencies The dependencies to pass into the
     *        constructor function.
     * @return This object container.
     */
    provide<T, I>(interfaceConstructor: Constructor<I> | AbstractConstructor<I>, implementationConstructor: Constructor<T>, dependencies?: any[]): this;
    /**
     * Retrieves the shared instance or value of the specified constant, alias,
     * class or factory function, interface, or fully qualified namespace path
     * (the method checks these in this order in case of a name clash).
     *
     * The instance or value is created lazily the first time it is requested.
     *
     * @param name The name
     *        of the alias, class, interface, or the class, interface or a
     *        factory function.
     * @return The shared instance or value.
     */
    get<T extends OCInstanceConstrain>(name: T): OCInstance<T>;
    /**
     * Returns the class constructor function of the specified class.
     *
     * @param name The name by which the class
     *        is registered with this object container.
     * @return The constructor function.
     */
    getConstructorOf<T extends keyof OCAliasMap | Constructor<any>>(name: T): Constructor<T> | null;
    /**
     * Returns `true` if the specified object, class or resource is
     * registered with this object container.
     *
     * @param name The resource name.
     * @return `true` if the specified object, class or
     *         resource is registered with this object container.
     */
    has<T>(name: keyof OCAliasMap | OCInjectable<T>): boolean;
    /**
     * Creates a new instance of the class or retrieves the value generated by
     * the factory function identified by the provided name, class, interface,
     * or factory function, passing in the provided dependencies.
     *
     * The method uses the dependencies specified when the class, interface or
     * factory function has been registered with the object container if no
     * custom dependencies are provided.
     *
     * @param name The name
     *        of the alias, class, interface, or the class, interface or a
     *        factory function to use.
     * @param dependencies The dependencies to pass into the
     *        constructor or factory function.
     * @return Created instance or generated value.
     */
    create<T extends OCInstanceConstrain>(name: T, dependencies?: any[]): OCInstance<T>;
    /**
     * Clears all entries from this object container and resets the locking
     * mechanism of this object container.
     *
     * @return This object container.
     */
    clear(): this;
    setBindingState(bindingState: BindingState, bindingPluginName?: string): void;
    /**
     * Retrieves the entry for the specified constant, alias, class or factory
     * function, interface, or fully qualified namespace path (the method
     * checks these in this order in case of a name clash).
     *
     * The method retrieves an existing entry even if a qualified namespace
     * path is provided (if the target class or interface has been configured
     * in this object container).
     *
     * The method throws an {@link Error} if no such constant, alias,
     * registry, interface implementation is known to this object container and
     * the provided identifier is not a valid namespace path specifying an
     * existing class, interface or value.
     *
     * @param  name Name of a constant or alias,
     *        factory function, class or interface constructor, or a fully
     *        qualified namespace path.
     * @return The retrieved entry.
     * @throws If no such constant, alias, registry, interface
     *         implementation is known to this object container.
     */
    _getEntry<T>(name: Dependency<T>): Entry<T> | null;
    /**
     * Checks whether the name is marked as optional.
     *
     * @param name Name of a constant or alias,
     *        factory function, class or interface constructor, or a fully
     *        qualified namespace path.
     */
    _isOptional<T>(name: Dependency<T>): boolean;
    /**
     * Checks whether the name is marked as spread.
     *
     * @param name Name of a constant or alias,
     *        factory function, class or interface constructor, or a fully
     *        qualified namespace path.
     */
    _isSpread<T>(name: Dependency<T>): boolean;
    /**
     * The method update classConstructor and dependencies for defined entry.
     * The entry throw Error for constants and if you try override dependencies
     * more than once.
     *
     * @param classConstructor The
     *        class constructor or factory function.
     * @param entry The entry representing the class that should
     *        have its instance created or factory faction to use to create a
     *        value.
     * @param dependencies The dependencies to pass into the
     *        constructor or factory function.
     */
    _updateEntryValues<T, E extends Entry<T>>(entry: E, classConstructor: OCInjectable<T>, dependencies: any[]): void;
    /**
     * Creates a new entry for the provided class or factory function, the
     * provided dependencies and entry options.
     *
     * @template T
     * @param classConstructor The
     *        class constructor or factory function.
     * @param dependencies The dependencies to pass into the
     *        constructor or factory function.
     * @param options
     * @return Created instance or generated value.
     */
    _createEntry<T>(classConstructor: EntryConstructor<T>, dependencies?: any[], options?: EntryOptions): Entry<T>;
    /**
     * Creates a new instance of the class or retrieves the value generated by
     * the factory function represented by the provided entry, passing in the
     * provided dependencies.
     *
     * The method uses the dependencies specified by the entry if no custom
     * dependencies are provided.
     *
     * @param entry The entry representing the class that should
     *        have its instance created or factory faction to use to create a
     *        value.
     * @param dependencies The dependencies to pass into the
     *        constructor or factory function.
     * @return Created instance or generated value.
     */
    _createInstanceFromEntry<T, E extends Entry<T>>(entry: E, dependencies?: any[]): InstanceType<Constructor<T>>;
    /**
     * Retrieves the constant value denoted by the provided fully qualified
     * composition name.
     *
     * The method returns the entry for the constant if the constant is registered
     * with this object container, otherwise return `null`.
     *
     * Finally, if the constant composition name does not resolve to value,
     * the method return `null`.
     *
     * @param compositionName
     * @return An entry representing the value at the specified
     *         composition name in the constants. The method returns `null`
     *         if the specified composition name does not exist in the constants.
     */
    _getEntryFromConstant<T>(compositionName: string): Entry<() => T> | null;
    /**
     * Retrieves the class denoted by the provided fully qualified name within
     * the application namespace.
     *
     * The method then checks whether there are dependencies configured for the
     * class, no matter whether the class is an implementation class or an
     * "interface" class.
     *
     * The method returns the entry for the class if the class is registered
     * with this object container, otherwise an unregistered entry is created
     * and returned.
     *
     * Finally, if the namespace path does not resolve to a class, the method
     * return an unregistered entry resolved to the value denoted by the
     * namespace path.
     *
     * Alternatively, if a constructor function is passed in instead of a
     * namespace path, the method returns `null`.
     *
     * @param path Namespace path pointing to
     *        a class or a value in the application namespace, or a constructor
     *        function.
     * @return An entry representing the value or class at the
     *         specified path in the namespace. The method returns `null`
     *         if the specified path does not exist in the namespace.
     */
    _getEntryFromNamespace<T>(path: string): Entry<T> | null;
    /**
     * Retrieves the class denoted by the provided class constructor.
     *
     * The method then checks whether there are defined `$dependencies`
     * property for class. Then the class is registered to this object
     * container.
     *
     * The method returns the entry for the class if the specified class
     * does not have defined `$dependencies` property return
     * `null`.
     *
     * @param classConstructor
     * @return An entry representing the value at the specified
     *         classConstructor. The method returns `null`
     *         if the specified classConstructor does not have defined
     *         `$dependencies`.
     */
    _getEntryFromClassConstructor<T>(classConstructor: OCInjectable<T>): Entry<T> | null;
}
export {};
//# sourceMappingURL=ObjectContainer.d.ts.map