反转圆形单次注射

时间:2017-11-21 14:17:52

标签: dependency-injection singleton inversifyjs

我正在尝试使用两个单身,让他们能够像这样打电话给对方

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

let container = new Container();

@injectable()
class Dom {
  private domUi: DomUi;

  constructor (domUi: DomUi) {
    this.domUi = domUi;
  }
}

@injectable()
class DomUi {
  private dom: Dom;

  constructor (dom: Dom) {
    this.dom = dom;
  }
}

@injectable()
class Test {
  constructor (dom: Dom) {
    console.log(dom);
  }
}

container.bind<Dom>(Dom).toSelf().inSingletonScope();
container.bind<DomUi>(DomUi).toSelf().inSingletonScope();

const test = container.resolve(Test);

但它给出了这个错误

Error: Missing required @inject or @multiInject annotation in: argument 0 in class Dom.

如何解决这个问题?我试了@inject@multiInject但没有运气! 从设计模式的角度来看,有没有更好的方法来考虑这个问题?

1 个答案:

答案 0 :(得分:1)

我认为您发现了一个错误,您可以使用以下方法作为解决方法:

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

let container = new Container();
let { lazyInject } = getDecorators(container);

@injectable()
class DomUi {
    private _dom: Dom;

    public constructor (dom: Dom) {
        this._dom = dom;
    }
}

@injectable()
class Dom {
    @lazyInject(DomUi) private domUi: DomUi;
}

@injectable()
    class Test {
    constructor(dom: Dom) {
        console.log(dom);
    }
}

container.bind<Dom>(Dom).toSelf().inSingletonScope();
container.bind<DomUi>(DomUi).toSelf().inSingletonScope();
const dom = container.resolve(Test);

推荐的实现方式是使用符号而不是类ID:

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

let container = new Container();
let { lazyInject } = getDecorators(container);

const TYPE = {
    Dom: Symbol("Dom"),
    DomUi: Symbol("DomUi"),
    Test: Symbol("Test")
};

interface Dom {}
interface DomUi {}
interface Test {}

@injectable()
class DomUi {
    public dom: Dom;

    public constructor (
        @inject(TYPE.Dom) d: Dom
    ) {
        this.dom = d;
    }
}

@injectable()
class Dom {
    @lazyInject(TYPE.DomUi) public domUi: DomUi;
}

@injectable()
class Test {
    constructor(
        @inject(TYPE.Dom) d: Dom
    ) {
        console.log(d, d.domUi.dom);
    }
}

container.bind<Dom>(TYPE.Dom).to(Dom).inSingletonScope();
container.bind<DomUi>(TYPE.DomUi).to(DomUi).inSingletonScope();
container.bind<Test>(TYPE.Test).to(Test);
const dom = container.get(TYPE.Test);