在NestJS中使用非构造函数DI时如何将provider设为可选
NestJS 非构造注入场景可选Provider实现方案
针对NestJS中仅构造函数注入支持@Optional()装饰器,factory provider等非构造注入场景无法直接使用该装饰器的问题,可通过以下对应方案实现可选依赖功能:
1. Factory Provider(useFactory)场景
Nest 7及以上版本支持在inject数组中使用对象语法标记依赖为可选:
const customFactoryProvider = { provide: 'MY_CUSTOM_SERVICE', useFactory: (optionalDependency: OptionalService | null) => { // 依赖不存在时会自动传入null,可自行兜底处理 return new MyCustomService(optionalDependency ?? new DefaultOptionalService()); }, inject: [ { token: OptionalService, optional: true, // 标记该依赖为可选 }, ], };
标记optional: true后,若对应token的Provider未在模块中注册,不会抛出依赖未找到的异常。
2. 动态获取Provider(ModuleRef)场景
如果是通过ModuleRef主动获取Provider的场景,调用获取方法时传入可选配置即可:
import { Injectable, ModuleRef } from '@nestjs/core'; @Injectable() export class DemoService { constructor(private moduleRef: ModuleRef) {} async handleBusiness() { // 同步获取单例Provider const optionalSingleton = this.moduleRef.get(OptionalService, { optional: true }); // 异步获取请求/ transient作用域Provider const optionalScopedService = await this.moduleRef.resolve( OptionalService, undefined, { optional: true } ); // 依赖不存在时返回undefined,自行判断逻辑 if (optionalSingleton) { optionalSingleton.doSomething(); } } }
3. 属性注入场景
如果使用属性注入而非构造函数注入,可直接组合使用@Optional()和@Inject()装饰器:
import { Inject, Injectable, Optional } from '@nestjs/common'; @Injectable() export class DemoService { @Optional() @Inject(OptionalService) private optionalService?: OptionalService; }
内容的提问来源于stack exchange,提问作者Ginden
相关产品推荐
相关产品推荐

