import {AbstractFactory} from './AbstractFactory' import { DEPENDENCY_KEYS_METADATA_KEY, DependencyRequirement, Instantiable, PropertyDependency, } from '../types' import {Collection} from '../../util' import 'reflect-metadata' /** * Standard static-class factory. The token of this factory is a reference to a * static class that is instantiated when the factory produces. * * Dependency keys are inferred from injection metadata on the constructor's params, * as are the injected properties. * * @example * ```typescript * class A { * constructor( * protected readonly myService: MyService * ) { } * } * * const fact = new Factory(A) * * fact.produce([myServiceInstance], []) // => A { myService: myServiceInstance } * ``` */ export class Factory extends AbstractFactory { constructor( protected readonly token: Instantiable, ) { super(token) } produce(dependencies: any[], parameters: any[]): any { return new this.token(...dependencies, ...parameters) } match(something: unknown): boolean { return something === this.token // || (something?.name && something.name === this.token.name) } getDependencyKeys(): Collection { const meta = Reflect.getMetadata(DEPENDENCY_KEYS_METADATA_KEY, this.token) if ( meta ) { return meta } return new Collection() } getInjectedProperties(): Collection { return this.getInjectedPropertiesForPrototypeChain(this.token) } }