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

NestJS中注入的Web3实例跨服务共享如何配置独立实例

NestJS 多服务注入独立Web3实例配置方案

问题原因

你当前配置出现实例共享的核心原因有两个:

  • NestJS默认所有provider都是单例作用域,整个应用生命周期内同一个注入令牌(这里是Web3类)只会对应一个实例,所有依赖该令牌的服务都会拿到同一个实例
  • 你使用了useValue写法注册Web3:useValue是直接将你提前创建好的new Web3()实例交给Nest容器管理,容器不会再生成新实例,无论怎么调整作用域都只会返回这一个固定对象。

可行解决方案

方案1:自定义专属注入令牌(推荐,粒度最可控)

不要让两个服务共用同一个Web3注入令牌,给每个服务单独定义专属的注入令牌,每个令牌对应独立的Web3实例,这种方式不需要修改服务默认作用域,性能最优。

  1. 先定义两个专属注入常量:
// 可以放在模块的constants文件里
export const ETH_WEB3 = Symbol('ETHEREUM_WEB3');
export const BSC_WEB3 = Symbol('BINANCE_WEB3');
  1. 修改模块的providers配置,为每个令牌单独注册实例:
@Module({
  imports: [ConfigModule.forRoot(), HelperModule],
  providers: [
    NEtheriumChainService,
    NBinanceChainService,
    NBitcoinChainService,
    NChainServiceProvider,
    {
      provide: ETH_WEB3,
      useFactory: () => new Web3(),
    },
    {
      provide: BSC_WEB3,
      useFactory: () => new Web3(),
    },
  ],
  exports: [NChainServiceProvider],
})
export class NChainsModule {}
  1. 在对应服务的构造函数中,用@Inject()指定要注入的专属令牌:
// NEtheriumChainService 中
@Injectable()
export class NEtheriumChainService {
  constructor(
    @Inject(ETH_WEB3) private readonly web3: Web3
  ) {}
}

// NBinanceChainService 中
@Injectable()
export class NBinanceChainService {
  constructor(
    @Inject(BSC_WEB3) private readonly web3: Web3
  ) {}
}

这种方式下两个服务拿到的Web3实例完全独立,且实例只在模块初始化时创建一次,不会产生额外的性能开销,后续如果需要给其他链服务配置独立Web3实例,只需要新增对应令牌和provider即可。


方案2:设置Web3为瞬态作用域

如果你不想自定义注入令牌,可以把Web3 provider的作用域设置为TRANSIENT(瞬态),瞬态作用域的provider会在每个消费它的服务初始化时,单独创建一个新实例。
注意必须把useValue换成useFactory,否则作用域配置不生效:

import { Scope } from '@nestjs/common';

@Module({
  imports: [ConfigModule.forRoot(), HelperModule],
  providers: [
    NEtheriumChainService,
    NBinanceChainService,
    NBitcoinChainService,
    NChainServiceProvider,
    {
      provide: Web3,
      useFactory: () => new Web3(),
      scope: Scope.TRANSIENT,
    },
  ],
  exports: [NChainServiceProvider],
})
export class NChainsModule {}

这种写法不需要修改服务内的注入代码,直接在构造函数注入Web3即可。但要注意:后续所有注入Web3的服务都会拿到全新的独立实例,如果需要部分服务共享Web3实例,这种方式无法做到细粒度控制。

注意:不要使用Scope.REQUEST作用域,该作用域会在每一次请求进入时都创建新的Web3实例,会产生不必要的性能损耗,不符合服务持有固定独立实例的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:39:49