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

如何在tsyringe中实现策略模式动态注入且不污染依赖容器?

使用tsyringe实现策略模式:不污染容器的动态注入方案

问题场景

需要为Test类动态注入不同的策略实现(Thing1/Thing2),但不希望修改全局依赖容器,避免后续实例化时意外使用错误策略。

解决方案

1. 临时覆盖依赖(推荐)

利用tsyringe的container.resolve方法内置的overrides参数,临时指定当前实例的依赖,不会修改全局容器的注册信息。

首先给Test的构造参数定义一个统一令牌:

interface IThing {
  exec(): void;
}

@injectable()
class Thing1 implements IThing {
  exec(): void {
    console.log('thing 1');
  }
}

@injectable()
class Thing2 implements IThing {
  exec(): void {
    console.log('thing 2');
  }
}

@injectable()
class Test {
  constructor(
    @inject('IThing') // 定义统一令牌
    private readonly thing: IThing,
  ) {
    thing.exec();
  }
}

然后在实例化Test时,通过overrides临时注入对应策略:

// 注入Thing1的实例
const testWithThing1 = container.resolve(Test, {
  overrides: [
    { token: 'IThing', useClass: Thing1 },
  ],
});

// 注入Thing2的实例
const testWithThing2 = container.resolve(Test, {
  overrides: [
    { token: 'IThing', useClass: Thing2 },
  ],
});

这种方式仅对当前resolve生成的实例生效,完全不会污染全局容器。

2. 工厂类封装策略注入

如果需要更灵活的策略管理,可以创建工厂类来封装Test的实例化逻辑,手动传入策略实例:

@injectable()
class TestFactory {
  createTest(thing: IThing): Test {
    // 若Test有其他依赖,可结合container.resolve和overrides
    return container.resolve(Test, {
      overrides: [{ token: 'IThing', useValue: thing }],
    });
  }
}

// 使用方式
const factory = container.resolve(TestFactory);
// 直接从容器获取策略实例并传入
const test1 = factory.createTest(container.resolve(Thing1));
const test2 = factory.createTest(container.resolve(Thing2));

这种方式将策略选择逻辑集中在工厂类中,代码可读性更强,同时避免全局容器污染。

3. 动态策略工厂(复杂场景适用)

如果策略实例的创建需要依赖其他服务,可以注册一个工厂令牌,根据参数动态返回对应策略:

// 注册策略工厂,用于根据类型生成对应策略实例
container.register('ThingStrategyFactory', {
  useFactory: (container) => {
    return (strategyType: 'Thing1' | 'Thing2') => {
      switch(strategyType) {
        case 'Thing1':
          return container.resolve(Thing1);
        case 'Thing2':
          return container.resolve(Thing2);
        default:
          throw new Error(`Unsupported strategy type: ${strategyType}`);
      }
    };
  },
});

// 修改Test类,注入工厂和策略类型
@injectable()
class Test {
  private readonly thing: IThing;

  constructor(
    @inject('ThingStrategyFactory') private readonly strategyFactory: (type: string) => IThing,
    @inject('TargetStrategy') private readonly targetStrategy: string,
  ) {
    this.thing = this.strategyFactory(this.targetStrategy);
    this.thing.exec();
  }
}

// 实例化时指定目标策略
const test1 = container.resolve(Test, {
  overrides: [
    { token: 'TargetStrategy', useValue: 'Thing1' },
  ],
});

const test2 = container.resolve(Test, {
  overrides: [
    { token: 'TargetStrategy', useValue: 'Thing2' },
  ],
});

该方案适合策略依赖其他服务的复杂场景,同样不会修改全局容器的注册状态。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:28:17