反转循环单例注入

Inversify circular singleton injection

我正在尝试使用两个单例并使它们能够像这样相互调用

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 但没有成功!
有没有更好的方法从设计模式的角度考虑这个问题?

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

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);