You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript的tsyringe中配置DI容器,使Foo复用FooBar的Bar实例?

解决tsyringe中FooBar与内部Foo共享同一Bar实例的问题

你的问题核心是要让每个FooBar实例拥有专属的Bar实例,并且该FooBar内部的Foo也共享这个Bar实例——而当前代码中tsyringe会分别为FooBar和Foo创建独立的Bar实例,导致断言失败。

下面提供两种简洁的解决方案,适配不同的场景:

方法1:使用容器作用域(Container Scoped)+ 子容器

这是最贴合DI设计思想的方案,通过ContainerScoped生命周期和子容器,为每个FooBar实例创建独立的上下文,确保同一上下文内的Bar实例唯一:

import { injectable, container, Lifecycle, scoped } from "tsyringe";

it("injects one Bar instance per FooBar", () => {
  // 标记Bar为容器作用域:每个容器实例仅创建一个Bar
  @scoped(Lifecycle.ContainerScoped)
  class Bar {
    constructor() {}
    x = 1;
  }

  @injectable()
  class Foo {
    constructor(public myBar: Bar) {}
  }

  @injectable()
  class FooBar {
    constructor(public bar: Bar, public foo: Foo) {}
  }

  // 为每个FooBar创建独立的子容器
  const childContainer = container.createChildContainer();
  const fooBar = childContainer.resolve(FooBar);
  
  fooBar.bar.x = 2;
  expect(fooBar.foo.myBar.x).toBe(2); // 断言通过
});

原理说明

Lifecycle.ContainerScoped会让tsyringe在同一个容器实例中只创建一个Bar实例。我们为每个FooBar创建子容器后,resolve出的FooBar和它内部的Foo都会从这个子容器获取Bar,自然共享同一实例。

方法2:工厂注入(手动控制实例传递)

如果不想引入子容器,可以通过注册工厂函数,让FooBar自己创建Bar实例并传递给Foo,实现实例共享:

import { injectable, container, inject } from "tsyringe";

it("injects one Bar instance per FooBar via factory", () => {
  @injectable()
  class Bar {
    constructor() {}
    x = 1;
  }

  @injectable()
  class Foo {
    constructor(public myBar: Bar) {}
  }

  @injectable()
  class FooBar {
    public bar: Bar;
    public foo: Foo;

    // 注入Foo的工厂函数,接收Bar实例并返回Foo
    constructor(@inject("FooFactory") fooFactory: (bar: Bar) => Foo) {
      this.bar = new Bar(); // 创建当前FooBar专属的Bar
      this.foo = fooFactory(this.bar); // 将Bar传递给Foo
    }
  }

  // 注册Foo的工厂函数
  container.register("FooFactory", {
    useFactory: () => (bar: Bar) => new Foo(bar)
  });

  const fooBar = container.resolve(FooBar);
  fooBar.bar.x = 2;
  expect(fooBar.foo.myBar.x).toBe(2); // 断言通过
});

适用场景

当你需要更精细地控制实例的创建时机,或者不想依赖容器作用域时,这种方式更灵活。


内容的提问来源于stack exchange,提问作者Obiwahn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:03:00