NestJS 使用保留在依赖注入层中的自定义参数创建一个新实例

Ben*_*eri 9 node.js typescript nestjs

我试图在不破坏 DI 层的情况下创建一个新实例,从而允许我的实例访问其构造函数中使用的所有可注入服务

我目前拥有的示例不允许我使用任何可注入服务:

const camera: Camera = new Camera(id, options);
Run Code Online (Sandbox Code Playgroud)

使用这种方法,相机类无法导入任何可注入的单例或类。

我在这里读到您可以使用它moduleRef来创建新实例,因此我尝试了以下操作:

const camera: Camera = await this.moduleRef.create(Camera);
Run Code Online (Sandbox Code Playgroud)

但现在的问题是,我无法传递IDOptions参数,唯一的解决方案是在初始化后立即使用设置器。

问题:

如何创建一个类的新实例(不是单例),由 Nest 的注入器创建并在最新版本的 NestJS 中创建时传递自定义参数?

Yev*_*nii 9

自定义提供程序就是您所需要的,您可以在此处找到文档

如果你想将它注入到你的某些模块中,请尝试这种方式

@Module({
   ...
   providers: [
      {
         useFactory: (optProvider) => {
           return new Camera(optProvider.id, optProvider.options);
         }, 
         provide: Camera,
         import: [OptProvider] // pay attention that OptProvider is a valid provider in this module
      },
      SomeService
   ]
})
export class SomeModule {}
Run Code Online (Sandbox Code Playgroud)

之后你可以通过 DI 提供这个对象

export class SomeService() {
  constructor( protected readonly camera: Camera ) {}
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿,谢谢您的时间和回答。这仍然不能回答我的问题,因为通过这种方式,您只能在模块中注入现有的可注入项,而不能注入通过 moduleRef 传递的自定义值! (2认同)

小智 8

我们有同样的问题。我们解决这个问题的方法是使用 useFactory,我们不是返回值,而是重新调整了一个工厂函数,除了额外的参数,我们用它来创建新实例。就像这样:

   const factory = {
  provide: PUPPETEER_FACTORY,
  useFactory: (configService): PuppeteerFactory => {
    return {
      create: function(config?: PuppeteerConfig) {
        return new Puppeteer(configService, config);
      }
    };
  },
  inject: [ConfigService]
};
Run Code Online (Sandbox Code Playgroud)

然后您只需使用返回的 create 函数,如下所示:

constructor(@Inject(PUPPETEER_FACTORY) private puppeteerFactory: PuppeteerFactory) {}
this.puppeteerInstance = this.puppeteerFactory.create({
      timezone: "UTC+8",
      userAgent: "BLA"
    });
Run Code Online (Sandbox Code Playgroud)

请注意,PUPPETEER_FACTORY 是一个 const