在反转中将属性注入的类绑定到内核

时间:2016-08-12 22:23:44

标签: typescript dependency-injection inversifyjs

我试图通过inversify在我的节点项目上实现依赖注入。

我有一个像这样的内核配置:inversify.config.ts

import "reflect-metadata";
import {Kernel, interfaces} from "inversify";

import {Config} from "./config";
import {Collection} from "./collection";

let kernel = new Kernel();

kernel.bind<Config>("Config").to(Config).inSingletonScope();
// kernel.bind<interfaces.Newable<Collection>>("Collection").toConstructor<Collection>(Collection);
// it works without the line above

课程:config.ts

import {injectable} from "inversify";
@injectable()
export class Config {
  constructor() {}
}

属性为DI collection.ts

的类
import {injectable} from "inversify";
import getDecorators from "inversify-inject-decorators";
import kernel from "../inversify.config";
let {lazyInject} = getDecorators(kernel);

@injectable()
export class Collection {
  @lazyInject(Config)
  private Config: Config;

  constructor(a: string, b: string) {}
}

如果我没有通过属性注入绑定一个类,那么一切都按预期工作。当我尝试使用@lazyInject绑定一个类时,如示例

所示
kernel.bind<interfaces.Newable<Collection>>("Collection").toConstructor<Collection>(Collection);

inversify.config.ts中的导入行开始处理Collection.ts和行

import kernel from "../inversify.config";`

在里面。但是,当我们处理Collection.ts文件行

时,我们已到达inversify.config.ts
import kernel from "../inversify.config";`

以某种方式返回undefinedundefined类创建内核Collection。因此@lazyInject DI失败。

最后,当我尝试阅读Config中的Collection时,它失败了:

TypeError: Cannot read property 'get' of undefined
    at resolve (node_modules/inversify-inject-decorators/lib/decorators.js:24:30)
    at Category.getter (node_modules/inversify-inject-decorators/lib/decorators.js:6:47)

我想知道是否有办法通过@lazyInject 来完成与属性DI的绑定,而将内核定义移动到与其中一个类相同的文件中。我正在寻找一种方法来实现导入内核,但要使其正常工作。

1 个答案:

答案 0 :(得分:4)

你的问题是你有一个循环依赖:

enter image description here

我要更改你的代码并添加几个额外的文件。不是他不需要文件types.ts,但建议将所有类型标识符保存在一个位置。

更改代码后,依赖关系图将更改为以下内容:

enter image description here

尽管如此,我们已经消除了循环依赖。

inversify.config.ts

import "reflect-metadata";
import {Kernel, interfaces} from "inversify";
import getDecorators from "inversify-inject-decorators";
import { makeProvideDecorator } from "inversify-binding-decorators";

let kernel = new Kernel();
let {lazyInject} = getDecorators(kernel);
let provide = makeProvideDecorator(kernel);

export { lazyInject, provide };

types.ts

let TYPES = {
  Config: "Config",
  Collection: "Collection",
};

export default TYPES;

config.ts

import { provide } from "../inversify.config";
import TYPES from "./types";

@provide(TYPES.Config)
export class Config {
  constructor() {}
}

export default Config;

collection.ts

import { lazyInject, provide } from "../inversify.config";

@provide(TYPES.Collection)
export class Collection {
  @lazyInject(TYPES.Config)
  private Config: Config;
  constructor(a: string, b: string) {}
}

export default Collection;

main.ts

您需要在导入@provide时导入所有依赖项,然后生成绑定。

import Config from "./lib/config";
import Collection from "./models/collection";

//...

我们已经能够使用inversify-binding-decorators中的@provide装饰器消除循环依赖关系。