@difizen/mana-syringe
Version:
96 lines (84 loc) • 2.75 kB
text/typescript
/* 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;
}