Разделение файла конфигурации JS inversify на несколько файлов - PullRequest
1 голос
/ 16 апреля 2020

Я недавно наткнулся на бэкэнд-проект с использованием Typescript и хотел бы реализовать принцип Io C с помощью Inversify. js. Следуя официальной документации, у меня есть один огромный файл с именем inversify.config.ts, содержащий все мои интерфейсы и классы, которые их реализуют:

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;

Одна большая проблема в вышеупомянутой настройке - когда проект становится сложным, больше модулей добавлен в результате очень длинный конфигурационный файл (представьте, что у вас есть десятки модулей). Мой план состоит в том, чтобы разделить его на более мелкие конфигурационные файлы, при этом inversify.config.ts остается основным файлом.

рассмотрим следующие параметры:

. / Dependencies / interface / index.ts

import { Container } from 'inversify';
export type InversifyContainer = Container

export interface BasicInterface {
        register(container: InversifyContainer): void
        readonly types: Object
    }

. / зависимости / moduleA / 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'),
    }
}

. / зависимости / инвертировать. 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

Однако при этом всегда возникает ошибка, показывающая что-то вроде Cannot read property of ModuleARepo of undefined из типов. Я просмотрел inte rnet, но, кажется, никого не волнует, насколько длинным и грязным будет inversify.config.ts, если он находится в сложном проекте.

Надеюсь, что кто-то может помочь с этим:)

1 Ответ

1 голос
/ 17 апреля 2020

Прежде всего ваша проблема описана в do c, и имеет решение .

Ваше решение, как правило, правильное, но существует круговая зависимость

./dependencies/types.ts -> ./dependencies/moduleA/index.ts -> ./dependencies/types.ts

В types создается новый экземпляр класса, но модуль, содержащий определение класса, импортирует types. Вы не перечисляете этот импорт, но используете TYPES.ModuleARepo в bind.

Чтобы избежать этого, вы можете сделать types field stati c или переместить его из класса в отдельный экспортируемый объект. Как положительный побочный эффект этого, не будет необходимости создавать экземпляр класса в ./dependencies/types.ts.

На всякий случай, пожалуйста, имейте в виду, что если вы создаете экземпляр класса, который имеет Symbol в качестве поля, этот символ уникален для каждого экземпляра, так как Symbol('ModuleARepo') !== Symbol('ModuleARepo').

Детская площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...