UNPKG

aurelia-dependency-injection

Version:

A lightweight, extensible dependency injection container for JavaScript.

152 lines (140 loc) 5.41 kB
import './internal'; import { Resolver } from './resolvers'; import { Container } from './container'; import { metadata } from 'aurelia-metadata'; import { DependencyCtorOrFunctor, PrimitiveOrDependencyCtor, Impl, Args, DependencyCtor } from './types'; /** * Decorator: Specifies a custom registration strategy for the decorated * class/function. */ export function registration<TBase, TImpl extends Impl<TBase>, TArgs extends Args<TBase>>( value: Registration<TBase, TImpl, TArgs>) { return (target: DependencyCtor<TBase, TImpl, TArgs>) => { metadata.define(metadata.registration, value, target); }; } /** * Decorator: Specifies to register the decorated item with a "transient" * lifetime. */ export function transient<TBase, TImpl extends Impl<TBase>, TArgs extends Args<TBase>>( key?: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>) { return registration(new TransientRegistration<TBase, TImpl, TArgs>(key)); } /** * Decorator: Specifies to register the decorated item with a "singleton" * lifetime. */ export function singleton(registerInChild?: boolean); export function singleton<TBase, TImpl extends Impl<TBase>, TArgs extends Args<TBase>>( key?: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>, registerInChild?: boolean); export function singleton<TBase, TImpl extends Impl<TBase>, TArgs extends Args<TBase>>( keyOrRegisterInChild?: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs> | boolean, registerInChild: boolean = false) { return registration<TBase, TImpl, TArgs>( new SingletonRegistration<TBase, TImpl, TArgs>(keyOrRegisterInChild, registerInChild) ); } /** * Customizes how a particular function is resolved by the Container. */ export interface Registration< TBase, TImpl extends Impl<TBase>, TArgs extends Args<TBase>> { /** * Called by the container to register the resolver. * @param container The container the resolver is being registered with. * @param key The key the resolver should be registered as. * @param fn The function to create the resolver for. * @return The resolver that was registered. */ registerResolver( container: Container, key: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>, fn: DependencyCtorOrFunctor<TBase, TImpl, TArgs> ): Resolver; } /** * Used to allow functions/classes to indicate that they should be registered as * transients with the container. */ export class TransientRegistration<TBase, TImpl extends Impl<TBase>, TArgs extends Args<TBase>> implements Registration<TBase, TImpl, TArgs> { /** @internal */ public _key?: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>; /** * Creates an instance of TransientRegistration. * @param key The key to register as. */ constructor(key?: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>) { this._key = key; } /** * Called by the container to register the resolver. * @param container The container the resolver is being registered with. * @param key The key the resolver should be registered as. * @param fn The function to create the resolver for. * @return The resolver that was registered. */ public registerResolver( container: Container, key: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>, fn: DependencyCtorOrFunctor<TBase, TImpl, TArgs> ): Resolver { const existingResolver = container.getResolver(this._key || key); return existingResolver === undefined ? container.registerTransient<TBase, TImpl, TArgs>( (this._key || key) as string, fn as DependencyCtorOrFunctor<TBase, TImpl, TArgs>) : existingResolver; } } /** * Used to allow functions/classes to indicate that they should be registered as * singletons with the container. */ export class SingletonRegistration<TBase, TImpl extends Impl<TBase>, TArgs extends Args<TBase>> implements Registration<TBase, TImpl, TArgs> { /** @internal */ public _registerInChild: boolean; /** @internal */ public _key?: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>; /** * Creates an instance of SingletonRegistration. * @param key The key to register as. */ constructor( keyOrRegisterInChild?: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs> | boolean, registerInChild: boolean = false) { if (typeof keyOrRegisterInChild === 'boolean') { this._registerInChild = keyOrRegisterInChild; } else { this._key = keyOrRegisterInChild; this._registerInChild = registerInChild; } } /** * Called by the container to register the resolver. * @param container The container the resolver is being registered with. * @param key The key the resolver should be registered as. * @param fn The function to create the resolver for. * @return The resolver that was registered. */ public registerResolver( container: Container, key: PrimitiveOrDependencyCtor<TBase, TImpl, TArgs>, fn: DependencyCtorOrFunctor<TBase, TImpl, TArgs> ): Resolver { const targetContainer = this._registerInChild ? container : container.root; const existingResolver = targetContainer.getResolver(this._key || key); return existingResolver === undefined ? targetContainer.registerSingleton(this._key || key, fn) : existingResolver; } }