网站搜索

typescript - 使用 inversifyjs 将容器绑定注入到现有对象的实例中


基本上,我希望负责对象的构造,然后使用 inversify 绑定被 @inject 装饰的属性。

我以为我可以使用 createChild 来使用 toConstantValue 或甚至 toDynamicValue 将类型绑定到一个值;然而,似乎这两种方法都没有进行任何属性绑定。

示例

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

const container = new Container();
container.bind(Container).toConstantValue(container);

@injectable()
class Foo {
  @inject(Container)
  public container: Container;
}

describe("inversify", () => {
  it("should inject for ctor", () => { //                    PASS
    const c = container.createChild();
    c.bind(Foo).toSelf();
    const result = c.get(Foo);
    expect(result.container).toBeDefined();
  });

  it("should inject for dynamic value", () => { //           FAIL
    const c = container.createChild();
    c.bind(Foo).toDynamicValue(() => new Foo());
    const result = c.get(Foo);
    expect(result.container).toBeDefined();
  });

  it("should inject for const value", () => { //             FAIL
    const c = container.createChild();
    c.bind(Foo).toConstantValue(new Foo());
    const result = c.get(Foo);
    expect(result.container).toBeDefined();
  });
});

似乎应该有一种简单的方法来绑定属性,而无需将对象的构建延迟到Container中?

答案#1

您正在经历的是按设计预期的行为。以下是更多细节:

转为动态值

关于第一个测试案例。toDynamicValue 旨在用于 InversifyJS 无法创建实例的情况,例如,因为你正在注入某个由第三方库实现的东西。InversifyJS 不会参与创建实例,由你来正确地创建该实例。

it("should inject for dynamic value", () => {L
  const c = container.createChild();
  c.bind(Foo).toDynamicValue(() => new Foo());
  const result = c.get(Foo);
  expect(result.container).toBeDefined();
});

你可以在 toDynamicValue 中使用 context 参数来解析依赖项:

c.bind(Foo).toDynamicValue((context) => {
    const foo = new Foo();
    const container = context.container.get(Container)
    foo.container = container;
    return foo;
});

注意:也许 foo.container=context.container 就足够了。

到常量值

关于第二个测试用例:

it("should inject for const value", () => {
  const c = container.createChild();
  c.bind(Foo).toConstantValue(new Foo());
  const result = c.get(Foo);
  expect(result.container).toBeDefined();
});

这是预期的失败。使用 toConstantValue 时,您必须提供一个值。如何正确创建该值由您自己决定。在您的示例中,您使用了 new Foo(),InversifyJS 不会参与值的创建,因为 toConstantValue 是一个用于在需要注入没有构造函数的东西时注入变量的特性(例如 process.env.SOME_ENV_VAR)。