/** * 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 };