import 'reflect-metadata' ; import { Type , IProviderClass , TInjectItem } from '../types' ; import { Injector , metadataOfInject , metadataOfPropInject } from '../core' ; import { rootInjector } from '../core' ; export class export class InjectionToken < T = any > { private _desc : string ; constructor ( _desc , options ? ) { this . _desc = _desc ; if ( options && options . factory ) { if ( options . providedIn === 'root' ) rootInjector . setProvider ( this , { provide : this , useFactory : options . factory } ) ; if ( options . providedIn && ( options . providedIn as any ) . nvType === 'nvModule' ) { ( ( options . providedIn as any ) . prototype as IProviderClass ) . $providers . push ( { provide : this , useFactory : options . factory } ) ; } if ( ! options . providedIn ) { rootInjector . setProvider ( this , { provide : this , useFactory : options . factory } ) ; } } } public toString ( ) { return `InjectionToken ${ this . _desc }` ; } } export param { * } token returns { ( target : Object , propertyKey : string , parameterIndex ? : number ) => void } export function Inject ( options ? ) { return function ( target , propertyKey , parameterIndex ? ) { if ( ! parameterIndex && parameterIndex !== 0 ) { const propertyType = Reflect . getMetadata ( 'design:type' , target , propertyKey ) ; if ( ! options && ! propertyType ) throw new Error ( `attribute of ${ target } : ${ propertyKey } can't be injected because that '@Inject' can't find token and type of attribute!` ) ; const findToken = ( options && options . token ) ? options . token : ( options && options . injector ? propertyType : options ) ; const findInjector = ( options && options . injector ) ? options . injector : null ; const metadata = Reflect . getMetadata ( metadataOfPropInject , target . constructor ) || [ ] ; const data = { property : propertyKey , token : findToken , injector : findInjector } ; metadata . push ( data ) ; Reflect . defineMetadata ( metadataOfPropInject , metadata , target . constructor ) ; } else { const propertyTypeList = Reflect . getMetadata ( 'design:paramtypes' , target , propertyKey ) ; if ( ! options && ( ! propertyTypeList || ! propertyTypeList [ parameterIndex ] ) ) throw new Error ( `constructor's attribute of ${ target } : ${ propertyKey } can't be injected because that '@Inject' can't find token and type of attribute!` ) ; const findToken = ( options && options . token ) ? options . token : ( options && options . injector ? propertyTypeList [ parameterIndex ] : options ) ; const findInjector = ( options && options . injector ) ? options . injector : null ; const metadata = Reflect . getMetadata ( metadataOfInject , target ) || [ ] ; const data = { index : parameterIndex , token : findToken , injector : findInjector } ; metadata . push ( data ) ; Reflect . defineMetadata ( metadataOfInject , metadata , target ) ; } } ; }