Инициализация приложения TypeScript, использующая внедрение зависимостей - PullRequest
1 голос
/ 06 апреля 2019

Я создаю проект TypeScript, используя Webpack GitHub repo .По умолчанию приложение разрешает внедрение зависимостей, и я не вижу установленных пакетов, которые предоставляют IoC, поэтому я могу только предполагать, что в TypeScript уже есть какой-то базовый DI?Я не могу найти документацию по контейнеру TypeScript IoC.

Мне нужен какой-то способ настройки инициализации приложения, который не создает смешную цепочку DI с помощью оператора new.См. Пример ниже:

class Stage {
  constructor(
    private light: Light,
  ) { }
}

class App {
  constructor(
    private stage: Stage,
  ) { }
}

class Init {
  constructor(
    private app: App,
  ) { }
}

const init: Init = new Init(new App(new Stage()));

Кажется, мне нужно что-то сделать с распознавателем?Нужно ли устанавливать что-то вроде InversifyJS для достижения этой цели?

Я уверен, что что-то вроде приведенного ниже кода достижимо, но как мне сказать контейнеру IoC для разрешения зависимостей Init?Есть ли место, где я должен создать резольвер?

const init: Init = new Init();

1 Ответ

1 голос
/ 06 апреля 2019

У меня возникла та же проблема, в конце концов я использовал inversifyJS , который можно использовать с Typescript.

Библиотека довольно плотная, но она определенно может достичь того, что вынаходясь в поиске.Сначала вам нужно установить следующее:

npm install inversify reflect-metadata --save

И в вашем файле tsconfig.json внести следующие изменения:

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["es6"],
        "types": ["reflect-metadata"],
        "module": "commonjs",
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
    }
}

Затем, используя приведенный выше пример:

import { injectable, inject } from "inversify";
import "reflect-metadata";

@injectable()
class Stage {
  private light: Light;

  constructor(
    @inject(Light) light: Light,
  ) { 
     this.light = light;
  }
}

@injectable()
class App {
  private stage: Stage;
  constructor(
    @inject(Stage) stage: Stage,
  ) { 
     this.stage = stage;
  }
}

@injectable()
class Init {
  private app: App;
  constructor(
    @inject(App) app: App
  ) { 
    this.app = app;
  }
}

Затем вы должны создать файл inversify.config.ts.Это все ваши зависимости, которые будут вставлены:

import 'reflect-metadata';
import { Container } from "inversify";
// import all of the Stage/Light/etc. classes also

let DIContainer = new Container();
DIContainer.bind<Stage>(Stage).toSelf();
DIContainer.bind<Light>(Light).toSelf();


export default DIContainer;

Наконец, перейдите к файлу, в котором создан экземпляр вашего класса Init, и измените его следующим образом:

import 'reflect-metadata';
import DIContainer from '../src/dependencies';
// import Init class as well

const init: Init = DIContainer.resolve<Init>(Init);

Весьма вероятно, что я что-то забыл или где-то обнаружил ошибку, но это главная идея.Надеюсь, это поможет.

...