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

Nest.js:如何通过依赖注入(DI)向提供者构造函数传参?

解决依赖注入传递useProxy参数的方案

以下针对你的场景提供几种适配NestJS依赖注入机制的实现方案,根据你的实际需求选择即可:


方案1:全局配置式注入(固定代理开关)

如果useProxy是全局统一的配置(比如从环境变量读取),可以通过自定义提供者创建PuppeteerService实例时传入参数:

1.1 模块中注册自定义提供者

在对应模块(如AppModule)中,通过useFactory创建配置好的PuppeteerService实例:

@Module({
  providers: [
    {
      provide: PuppeteerService,
      useFactory: () => {
        // 这里可从环境变量、配置文件等获取值
        const useProxy = process.env.USE_PROXY === 'true';
        return new PuppeteerService(useProxy);
      },
    },
    WebScrapingService,
  ],
})
export class AppModule {}

1.2 使用方式

此时WebScrapingService注入的PuppeteerService已经是带有预设useProxy值的实例,直接使用即可:

@Injectable()
export class WebScrapingService {
  public constructor(private readonly puppeteerService: PuppeteerService) {}

  async startScraping() {
    // puppeteerService已根据全局配置初始化代理逻辑
    // 执行爬取操作
  }
}

方案2:动态参数传递(按需控制代理)

如果需要在WebScrapingService中动态决定是否使用代理,建议将useProxy从构造函数参数改为方法参数,避免DI实例化时的固定性:

2.1 修改PuppeteerService

添加动态创建页面的方法,允许传入useProxy覆盖默认配置:

@Injectable()
export class PuppeteerService {
  // 可选:保留默认代理配置
  private defaultUseProxy: boolean;

  public constructor(defaultUseProxy = false) {
    this.defaultUseProxy = defaultUseProxy;
  }

  async getPage(useProxy?: boolean): Promise<Page> {
    const shouldUseProxy = useProxy ?? this.defaultUseProxy;
    const browserOptions = {};

    if (shouldUseProxy) {
      // 初始化代理插件逻辑,例如puppeteer-extra-plugin-proxy
      // puppeteer.use(ProxyPlugin({ proxy: { address: 'xxx', port: 8080 } }));
    }

    const browser = await puppeteer.launch(browserOptions);
    return browser.newPage();
  }
}

2.2 在WebScrapingService中动态调用

@Injectable()
export class WebScrapingService {
  public constructor(private readonly puppeteerService: PuppeteerService) {}

  async scrapeWithProxy() {
    // 主动指定使用代理
    const page = await this.puppeteerService.getPage(true);
    await page.goto('https://target-site.com');
    // 爬取逻辑...
    await page.close();
  }

  async scrapeWithoutProxy() {
    // 指定不使用代理
    const page = await this.puppeteerService.getPage(false);
    // 爬取逻辑...
  }
}

方案3:解耦配置参数(令牌式注入)

如果需要将useProxy参数与服务解耦,方便后续修改配置来源,可以使用自定义令牌注入:

3.1 定义参数令牌

// 定义唯一令牌标识
export const USE_PROXY = 'USE_PROXY';

3.2 模块中注册参数与服务

@Module({
  providers: [
    {
      provide: USE_PROXY,
      useValue: true, // 可替换为从配置文件/数据库读取的动态值
    },
    PuppeteerService,
    WebScrapingService,
  ],
})
export class AppModule {}

3.3 修改PuppeteerService构造函数

通过@Inject装饰器注入令牌对应的参数:

@Injectable()
export class PuppeteerService {
  public constructor(@Inject(USE_PROXY) public useProxy?: boolean) {
    if (this.useProxy) {
      // 初始化代理插件
    }
  }
}

内容的提问来源于stack exchange,提问作者K T MOHAMMED SULAIM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:05:31