import { Dict } from './dict' ; import { Factory , FactoryDefinition } from './factory' ; export interface RegistrationOptions { singleton ? : boolean ; instantiate ? : boolean ; } export interface Injection { property : string ; source : string ; } export interface RegistryWriter { register ( specifier , factory , options ? ) : void ; unregister ( specifier ) : void ; registerOption ( specifier , option , value ) : void ; unregisterOption ( specifier , option ) : void ; registerInjection ( specifier , property , source ) : void ; } export interface RegistryReader { registration ( specifier ) : any ; registeredOption ( specifier , option ) : any ; registeredOptions ( specifier ) : any ; registeredInjections ( specifier ) : Injection [ ] ; } export interface RegistryOptions { fallback ? : RegistryReader ; } export interface RegistryAccessor extends RegistryReader , RegistryWriter { } export default class Registry implements RegistryAccessor { private _registrations : Dict < FactoryDefinition < any > > ; private _registeredOptions : Dict < any > ; private _registeredInjections : Dict < Injection [ ] > ; private _fallback : RegistryReader ; constructor ( options ? ) { this . _registrations = { } ; this . _registeredOptions = { } ; this . _registeredInjections = { } ; if ( options && options . fallback ) { this . _fallback = options . fallback ; } } register ( specifier , factoryDefinition , options ? ) { this . _registrations [ specifier ] = factoryDefinition ; if ( options ) { this . _registeredOptions [ specifier ] = options ; } } registration ( specifier ) { let registration = this . _registrations [ specifier ] ; if ( registration === undefined && this . _fallback ) { registration = this . _fallback . registration ( specifier ) ; } return registration ; } unregister ( specifier ) { delete this . _registrations [ specifier ] ; delete this . _registeredOptions [ specifier ] ; delete this . _registeredInjections [ specifier ] ; } registerOption ( specifier , option , value ) { let options = this . _registeredOptions [ specifier ] ; if ( ! options ) { options = { } ; this . _registeredOptions [ specifier ] = options ; } options [ option ] = value ; } registeredOption ( specifier , option ) { let result ; let options = this . registeredOptions ( specifier ) ; if ( options ) { result = options [ option ] ; } if ( result === undefined && this . _fallback !== undefined ) { result = this . _fallback . registeredOption ( specifier , option ) ; } return result ; } registeredOptions ( specifier ) { let options = this . _registeredOptions [ specifier ] ; if ( options === undefined ) { let type = specifier . split ( ':' ) [ 0 ] ; options = this . _registeredOptions [ type ] ; } return options ; } unregisterOption ( specifier , option ) { let options = this . _registeredOptions [ specifier ] ; if ( options ) { delete options [ option ] ; } } registerInjection ( specifier , property , source ) { let injections = this . _registeredInjections [ specifier ] ; if ( injections === undefined ) { this . _registeredInjections [ specifier ] = injections = [ ] ; } injections . push ( { property , source } ) ; } registeredInjections ( specifier ) { let type = specifier . split ( ':' ) [ 0 ] ; let injections = this . _fallback ? this . _fallback . registeredInjections ( specifier ) : [ ] ; Array . prototype . push . apply ( injections , this . _registeredInjections [ type ] ) ; Array . prototype . push . apply ( injections , this . _registeredInjections [ specifier ] ) ; return injections ; } }