/**
* The bean manager allows getting references to singleton objects, so-called beans.
*
* #### Bean
* A bean can be any object or even a primitive like a `boolean`. A bean is registered under some symbol in the bean manager. In most
* cases, the class of the bean is used as the symbol. You can then look up the bean under its registration symbol. A symbol is either
* a class type, an abstract class type, or a `Symbol`.
*
* #### Bean Scope
* Beans are application-scoped, sometimes also referred to as singleton objects.
*
* #### Bean Construction
* By default, the bean manager constructs beans lazily when looked up for the first time. Subsequent lookups then get the same bean instance.
* When registering a bean, however, you can instruct the bean manager to construct the bean eagerly at startup. Eager beans are constructed after
* all initializers complete.
*
* #### Registering Beans
* A bean is registered in the bean manager under some class type, abstract class type or `Symbol`. In most cases, the symbol is also the type of the bean
* instance but does not have to be. You can then look up the bean from the bean manager using that symbol.
*
* When registering a bean, you must tell the bean manager how to construct the bean. Different strategies are supported, as listed below.
*
* |Strategy|Description|Example|
* |-|-|-|
* |useClass |if to create an instance of a class |```Beans.register(Logger, {useClass: ConsoleLogger});```|
* |useClass (shorthand) |Shorthand syntax if class and lookup symbol are identical |```Beans.register(ConsoleLogger);```|
* |useValue |if to use a static value as bean |```Beans.register(LoggingConfig, {useValue: config});```|
* |useFactory |if to construct the bean with a factory function |```Beans.register(Logger, {useFactory: () => new ConsoleLogger()});```|
* |useExisting |if to create an alias for another bean registered in the bean manager |```Beans.register(Logger, {useExisting: ConsoleLogger});```|
*
* #### Registering multiple Beans on the same Symbol
* Multiple beans can be registered under the same symbol by setting the multi flag to `true`. When looking them up, they are returned in an array in registration order.
*
* ```ts
* Beans.register(MessageInterceptor, {useClass: MessageLoggerInterceptor, multi: true});
* ```
* #### Looking up Beans
* Beans are looked up using the symbol under which they were registered. The bean manager providers different methods to look up beans, as listed below.
*
* |Method|Description|
* |-|-|
* |`Beans.get` |Returns the bean registered under the given symbol. If no or multiple beans are registered under the passed symbol, an error is thrown. |
* |`Beans.opt` |Returns the bean registered under the given symbol, if any, or returns `undefined` otherwise. |
* |`Beans.all` |Returns all beans registered under the given symbol. Returns an empty array if no bean is found. |
*
* #### Replacing Beans
* A bean can be replaced by registering another bean under a bean's symbol. In turn, the replaced bean is disposed and unregistered.
*
* #### Decorating Beans
* The bean manager allows decorating a bean to intercept invocations to its methods and properties. Multiple decorators can decorate a single bean. Decoration
* takes place in decorator registration order.
*
* Decorators are registered in the bean manager using the `Beans.registerDecorator` method under the symbol of the bean to be decorated.
* As with the registration of a bean, you must tell the bean manager how to construct the decorator. For more information, see Bean Construction Strategies.
* Decorators must be registered before starting the bean manager.
*
* A decorator must implement the decorate method of the BeanDecorator interface and return the proxied bean. To proxy a bean, you can create a JavaScript proxy,
* or create an anonymous class delegating to the actual bean.
*
* #### Initializers
* Initializers help to run initialization tasks during startup. Initializers can specify a runlevel in which to execute. Initializers bound to lower
* runlevels execute before initializers of higher runlevels. Initializers of the same runlevel may execute in parallel.
*
* Initializers are registered in the bean manager using the `Beans.registerInitializer` method, passing a function or an initializer object, and optionally a runlevel.
* If not specifying a runlevel, the initializer is executed in runlevel 0, or in the default runlevel as specified when starting the bean manager.
*
* @category BeanManager
*/
declare class BeanManager {
private _beanRegistry;
private _decoratorRegistry;
private _initializers;
private _sequence;
private _runlevel$;
private _eagerBeansConstructed;
private _started;
/**
* Registers a bean under the given symbol.
*
* If not providing instructions, the given symbol is used as the constructor function to construct the bean.
*
* By default, bean construction is lazy, meaning that the bean is constructed when looked up for the first time.
* If another bean is registered under the same symbol, that other bean is disposed and replaced with the given bean.
* To register multiple beans on the same symbol, register it with the flag `multi` set to `true`.
*
* Beans can be registered, replaced or removed even after starting the bean manager.
*
* @param symbol - Symbol under which to register the bean.
* @param instructions - Control bean construction; see {@link BeanInstanceConstructInstructions} for more detail.
* @return handle to unregister the bean.
*/
register(symbol: Type | Type | AbstractType | AbstractType | symbol, instructions?: BeanInstanceConstructInstructions): Registration;
/**
* Registers a bean under the given symbol, but only if no other bean is registered under that symbol yet.
*
* For detailed information about how to register a bean, see {@link register}.
*
* @param symbol - Symbol under which to register the bean.
* @param instructions - Control bean construction; see {@link BeanInstanceConstructInstructions} for more detail.
* @return handle to unregister the bean.
*/
registerIfAbsent(symbol: Type | Type | AbstractType | AbstractType | symbol, instructions?: BeanInstanceConstructInstructions): Registration;
/**
* Registers a decorator to proxy a bean.
*
* The decorator is invoked when the bean is constructed. Multiple decorators can be registered to decorate a bean.
* They are invoked in the order as registered.
*
* Decorators must be registered before starting the bean manager.
*
* @param symbol - Identifies the bean(s) which to decorate. If multiple beans are registered under that symbol, they all are decorated.
* @param decorator - Specifies the decorator.
*/
registerDecorator>(symbol: Type | AbstractType | symbol, decorator: {
useValue: T;
} | {
useClass?: Type;
} | {
useFactory?: () => T;
}): void;
/**
* Registers an initializer that is executed when the bean manager starts. The bean manager is fully started when all initializers are completed.
*
* Initializers can specify a runlevel in which to execute. Initializers bound to lower runlevels execute before initializers of higher runlevels.
* Initializers of the same runlevel may execute in parallel. Runlevels must be >= 0;
*
* Initializers must be registered before starting the bean manager.
*/
registerInitializer(initializer: InitializerFn | {
useFunction?: InitializerFn;
useClass?: Type;
useExisting?: Type | AbstractType | symbol;
runlevel?: number;
}): void;
/**
* Returns the bean registered under the given symbol.
*
* By default, if no or multiple beans are registered under the given symbol, an error is thrown.
*
* @param symbol - Symbol to look up the bean.
* @param orElse - Controls what to do if no bean is found under the given symbol. If not set and if no bean is found, the bean manager throws an error.
* @throws if not finding a bean, or if multiple beans are found under the given symbol.
*/
get(symbol: Type | AbstractType | Type | AbstractType | symbol, orElse?: {
orElseGet?: T;
orElseSupply?: () => T;
}): T;
/**
* Returns the bean registered under the given symbol, if any, or returns `undefined` otherwise.
*
* @param symbol - Symbol to look up the bean.
* @throws if multiple beans are found under the given symbol.
*/
opt(symbol: Type | AbstractType | Type | AbstractType | symbol): T | undefined;
/**
* Returns all beans registered under the given symbol. Returns an empty array if no bean is found.
*
* @param symbol - Symbol to look up the beans.
*/
all(symbol: Type | AbstractType | Type | AbstractType | symbol): T[];
/**
* Starts the bean manager by running initializers and constructing eager beans. By default, constructs eager beans after
* all initializers completed.
*
* Initializers with a lower runlevel are executed before initializers with a higher runlevel. After all initializers of the
* same runlevel have completed, initializers of the next higher runlevel are executed, and so on. Initializers of the same
* runlevel may run in parallel.
*
* @param config - Control initialization of the bean manager.
* @return A Promise that resolves when all initializers completed.
*/
start(config?: BeanManagerConfig): Promise;
/**
* Destroys all beans managed by the bean manager.
*
* After calling this method, beans, initializers and decorators unregistered.
*
* Calling this method has no effect if the bean manager is not started, or failed to start.
*/
destroy(): void;
private disposeBean;
/**
* Returns a Promise that resolves when the bean manager enters the specified runlevel.
* The Promise resolves immediately when the bean manager has already entered or completed that runlevel.
*/
whenRunlevel(runlevel: number): Promise;
private getBeanInfos;
/**
* Runs registered initializers, where initializers with a lower runlevel are executed before initializers with a higher runlevel.
* After all initializers of the same runlevel have completed, initializers of the next higher runlevel are executed, and so on.
* Initializers of the same runlevel may run in parallel.
*/
private runInitializers;
/**
* Constructs beans with an eager construction.
*/
private constructEagerBeans;
/**
* Returns the bean instance if already constructed, or constructs the bean otherwise.
*/
private getOrConstructBeanInstance;
}
/**
* Provides access to beans registered in the bean manager.
*
* @category BeanManager
*/
declare const Beans: BeanManager;
/**
* Lifecycle hook will be executed before destroying this bean.
*
* @category BeanManager
*/
interface PreDestroy {
/**
* Method invoked before destroying this bean, e.g., when unregistering it, or when shutting down the bean manager.
*/
preDestroy(): void;
}
/**
* Describes how a bean instance is created.
*
* @category BeanManager
*/
interface BeanInstanceConstructInstructions {
/**
* Set if to use a static value as bean.
*/
useValue?: T;
/**
* Set if to create an instance of a class.
*/
useClass?: Type;
/**
* Set if to construct the instance with a factory function.
*/
useFactory?: () => T;
/**
* Set if to create an alias for another bean.
*/
useExisting?: Type | AbstractType | symbol;
/**
* Set if to construct the bean eagerly. By default, bean construction is lazy when the bean is looked up for the first time.
*/
eager?: boolean;
/**
* Set if to provide multiple beans for a single symbol.
*/
multi?: boolean;
/**
* Control when to destroy the bean when destroying the bean manager.
* Beans with a lower destroy order are destroyed before beans with a higher destroy order. Beans of the same destroy order
* are destroyed in reverse construction order.
*/
destroyOrder?: number;
}
/**
* Allows executing initialization tasks (synchronous or asynchronous) when starting the bean manager. The bean manager is fully started when all initializers are completed.
*
* Initializers can specify a runlevel in which to execute. Initializers bound to lower runlevels execute before initializers of higher runlevels.
* Initializers of the same runlevel may execute in parallel.
*
* @see {@link BeanManager.registerInitializer Beans.registerInitializer}
* @category BeanManager
*/
interface Initializer {
/**
* Executes some work during bean manager startup.
*
* @return a Promise that resolves when this initializer completes its initialization.
*/
init(): Promise;
}
/**
* Allows executing initialization tasks (synchronous or asynchronous) when starting the bean manager. The bean manager is fully started when all initializers are completed.
*
* Initializers can specify a runlevel in which to execute. Initializers bound to lower runlevels execute before initializers of higher runlevels.
* Initializers of the same runlevel may execute in parallel.
*
* The initializer function must return a Promise that resolves when completed its initialization.
*
* @see {@link BeanManager.registerInitializer Beans.registerInitializer}
* @category BeanManager
*/
declare type InitializerFn = () => Promise;
/**
* Allows intercepting bean method or property invocations.
* When the bean is constructed, it is passed to the decorator in order to be proxied.
*
* @see {@link BeanManager.registerDecorator Beans.registerDecorator}
* @category BeanManager
*/
interface BeanDecorator {
/**
* Method invoked when the bean is instantiated.
*
* @param bean - The actual bean instance; use it to delegate invoations to the actual bean.
* @return proxied bean
*/
decorate(bean: T): T;
}
/**
* Represents a symbol of an abstract class.
*
* @category BeanManager
*/
interface AbstractType extends Function {
prototype: T;
}
/**
* Represents a symbol of a class.
*
* @category BeanManager
*/
interface Type extends Function {
new (...args: any[]): T;
}
/**
* Handle to undo a registration.
*/
interface Registration {
unregister: () => void;
}
/**
* Control initialization of the bean manager.
*
* @category BeanManager
*/
interface BeanManagerConfig {
/**
* Defines the runlevel in which to construct eager beans.
* If not set, eager beans are constructed after all registered initializers completed.
*/
eagerBeanConstructRunlevel?: number;
/**
* Defines the runlevel in which initializers, that do not specify a runlevel, should be executed.
* If not set, initializers not specifying a runlevel are bound to the runlevel 0.
*/
initializerDefaultRunlevel?: number;
}
export { BeanManager, Beans };
export type { AbstractType, BeanDecorator, BeanInstanceConstructInstructions, BeanManagerConfig, Initializer, InitializerFn, PreDestroy, Registration, Type };