UNPKG

@difizen/mana-syringe

Version:

96 lines (84 loc) 2.75 kB
/* eslint-disable @typescript-eslint/no-invalid-this */ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { interfaces } from 'inversify'; import { ContainerModule } from 'inversify'; import { contributionInjectOption } from '../contribution/contribution-register'; import type { Syringe } from '../core'; import { Utils } from '../core'; import type { InversifyRegister } from '../inversify-api'; import { Register } from '../register'; type TokenOrOption<T> = Syringe.Token<T> | Syringe.InjectOption<T>; export class SyringeModule<T = Syringe.Module> implements Syringe.Module { protected dependencies: T[] = []; /** * @readonly * module unique id */ readonly id: number; protected moduleName?: string | undefined; readonly inversifyModule: ContainerModule; protected optionCollection?: (Syringe.Token<any> | Syringe.InjectOption<any>)[]; get name() { return this.moduleName; } constructor(name?: string) { this.moduleName = name; this.inversifyModule = new ContainerModule(this.inversifyRegister); this.id = this.inversifyModule.id; } protected inversifyRegister = ( bind: interfaces.Bind, unbind: interfaces.Unbind, isBound: interfaces.IsBound, rebind: interfaces.Rebind, ) => { const inversifyRegister: InversifyRegister = { bind, unbind, isBound, rebind, }; const register = <T = any>( token: Syringe.Token<T> | Syringe.InjectOption<T>, options: Syringe.InjectOption<T> = {}, ): void => { if (Utils.isInjectOption(token)) { Register.resolveOption({ container: inversifyRegister }, token); } else { Register.resolveTarget({ container: inversifyRegister }, token, options); } }; if (this.optionCollection) { this.optionCollection.forEach((option) => register(option)); } }; protected get options() { if (!this.optionCollection) { this.optionCollection = []; } return this.optionCollection; } register(...options: TokenOrOption<any>[]) { options.forEach((option) => this.options.push(option)); return this; } contribution(...tokens: Syringe.DefinedToken[]) { tokens.forEach((token) => this.options.push(contributionInjectOption(token))); return this; } dependOn(...modules: T[]) { this.dependencies.push(...modules); return this; } toLoader(): SyringeModuleLoader<T> { return { dependencies: this.dependencies.length > 0 ? this.dependencies : undefined, }; } } export interface SyringeModuleLoader<T = Syringe.Module> { dependencies?: T[]; } export function isSyringeModule(data: Syringe.Module): data is SyringeModule { return data && 'inversifyModule' in data; }