node.js - Dela upp inversifyJS-konfigurationsfilen i flera filer
Jag stötte nyligen på ett backend-projekt som använder Typescript och skulle vilja implementera IoC-principen med hjälp av Inversify.js. Följande den officiella dokumentationen har jag en stor fil som heter inversify.config.ts som innehåller alla mina gränssnitt och klasser som implementerar dem:
import "reflect-metadata"
import { Container } from "inversify"
import TYPES from './types';
import { ModuleRepo } from '../repo/interfaces'
import { ModuleARepoImpl } from '../repo/moduleA'
import { ModuleBRepoImpl } from '../repo/moduleB'
import { ModuleService } from '../services/interfaces'
import { ModuleAServiceImpl } from '../services/moduleA'
import { ModuleBServiceImpl } from '../services/moduleB'
const container = Container();
container.bind<ModuleRepo>(TYPES.ModuleARepo).to(ModuleARepoImpl);
container.bind<ModuleRepo>(TYPES.ModuleBRepo).to(ModuleBRepoImpl);
container.bind<ModuleService>(TYPES.ModuleAService).to(ModuleAServiceImpl);
container.bind<ModuleService>(TYPES.ModuleBService).to(ModuleBServiceImpl);
export default container;
Ett stort problem i ovanstående upplägg är när projektet blir komplext, fler moduler läggs till vilket resulterar i en mycket lång konfigurationsfil (föreställ dig att du har dussintals moduler). Min plan är att dela upp det i mindre konfigurationsfiler, där inversify.config.ts förblir huvudfilen.
överväg följande inställningar:
./beroenden/gränssnitt/index.ts
import { Container } from 'inversify';
export type InversifyContainer = Container
export interface BasicInterface {
register(container: InversifyContainer): void
readonly types: Object
}
./beroenden/modulA/index.ts
import {InversifyContainer, BasicDependencies} from '../interface';
import { ModuleRepo } from '../../repo/interfaces'
import { ModuleARepoImpl } from '../../repo/moduleA'
import { ModuleService } from '../../services/interfaces'
import { ModuleAServiceImpl } from '../../services/moduleA'
export class ModuleADependencies {
register(container: InversifyContainer) {
container.bind<ModuleRepo>(TYPES.ModuleARepo).to(ModuleARepoImpl);
container.bind<ModuleService>(TYPES.ModuleAService).to(ModuleAServiceImpl);
}
readonly types = {
ModuleARepo: Symbol('ModuleARepo'),
ModuleAService: Symbol('ModuleAService'),
}
}
./dependencies/inversify.config.ts
import "reflect-metadata"
import { Container } from "inversify"
import { ModuleADependencies } from './moduleA';
import { ModuleBDependencies } from './moduleB'; // consider moduleB also has the same file
const container = Container();
const registrationList = [ModuleADependencies, ModuleBDependencies];
for (const reg of registrationList) {
new reg().register(container);
}
export default container;
./dependencies/types.ts
import { ModuleADependencies } from './moduleA';
import { ModuleBDependencies } from './moduleB';
const TYPES = {
...(new ModuleADependencies().types),
...(new ModuleBDependencies().types),
}
export default TYPES
Men på detta sätt får jag alltid ett fel som visar något i stil med Cannot read property of ModuleARepo of undefined från typerna. Jag har sökt på internet men det verkar som att ingen bryr sig om hur lång och rörig inversify.config.ts skulle bli om det är i ett komplext projekt.
Hoppas att någon kan hjälpa till med detta :)
Svar #1
Först och främst beskrivs ditt problem i dokumentet och har en lösning.
Din lösning är generellt korrekt men det finns ett cirkulärt beroende
./dependencies/types.ts -> ./dependencies/moduleA/index.ts -> ./dependencies/types.ts
I types skapas en ny instans av klassen men modulen som innehåller klassdefinitionen importerar types. Du listar inte denna import men använder TYPES.ModuleARepo i bind.
För att undvika det kan du göra fältet types statiskt eller flytta det ur klassen till ett separat exporterbart objekt. Som en positiv bieffekt av detta kommer det inte att behövas att instansiera en klass i ./dependencies/types.ts.
Bara för säkerhets skull, vänligen kom ihåg att om du instansierar en klass som har en Symbol som fält, är denna symbol unik för varje instans eftersom Symbol('ModuleARepo') !== Symbol('ModuleARepo').
Lekplats
