I'm trying to use two singletons and make them able to call each other like this
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);
But it gives this error
Error: Missing required @inject or @multiInject annotation in: argument 0 in class Dom.
How can this be fixed? I tried the @inject
and @multiInject
with no luck!
is there a better way to think about this from a design pattern standpoint?
I think you have found a bug, you can use the following as a workaround:
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);
The recommended implementation would be with symbols not classes as IDs:
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);