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
相关产品推荐
相关产品推荐

