定制供应商
定制供应商
当您可能希望将某些内容直接
绑定到控件容器的Nest反转时,有很多场景。例如,任何常量值,基于当前环境创建的配置对象,外部库或依赖于少数其他已定义提供程序的预先计算的值。此外,您可以覆盖默认实现,例如,在需要时使用不同的类或使用各种测试双精度(用于测试目的)。
您应该始终牢记的一件重要事情是Nest使用令牌
来识别依赖关系。通常,自动生成的标记等于类。如果要创建自定义提供程序,则需要选择令牌
。大多数情况下,自定义标记由纯字符串表示。遵循最佳实践,您应该在分隔文件中保存这些标记,例如,在内部constants.ts
。
我们来看看可用的选项。
使用价值
在useValue
定义常量值,将外部库放入Nest容器或用mock对象替换实际实现时,语法很有用。
import { connection } from './connection';
const connectionProvider = {
provide: 'Connection',
useValue: connection,
};
@Module{
providers: [connectionProvider],
})
export class ApplicationModule {}
为了注入自定义提供程序,我们使用@Inject()
装饰器。这个装饰器只接受一个参数 - 令牌。
JS
@Injectable()
class CatsRepository {
constructor(@Inject('Connection') connection: Connection) {}
}
提示
该@Inject()
装饰器从进口@nestjs/common
包。
如果要覆盖默认提供程序的值,假设您希望强制Nest使用模拟,CatsService
由于测试目的,您可以简单地使用现有类作为标记。
import { CatsService } from './cats.service';
const mockCatsService = {};
const catsServiceProvider = {
provide: CatsService,
useValue: mockCatsService,
};
@Module{
imports: [CatsModule],
providers: [catsServiceProvider],
})
export class ApplicationModule {}
在上面的示例中,CatsService
将被传递的mockCatsService
模拟对象覆盖。这意味着,Nest而不是CatsService
手动创建实例,会将此提供程序视为已解决,并将mockCatsService
其用作其代表值。
使用课程
该useClass
语法允许您选择每使用因素不同的类。例如,我们有一个抽象(或默认)ConfigService
类。根据当前环境,Nest应使用配置服务的不同实现。
const configServiceProvider = {
provide: ConfigService,
useClass: process.env.NODE_ENV === 'development'
? DevelopmentConfigService
: ProductionConfigService,
};
@Module{
providers: [configServiceProvider],
})
export class ApplicationModule {}
注意
我们使用了ConfigService
类而不是自定义标记,因此我们已经覆盖了默认实现。
在这种情况下,即使任何类依赖ConfigService
,Nest也会注入所提供的类(DevelopmentConfigService
或ProductionConfigService
)的实例。
使用工厂
这useFactory
是一种动态
创建提供程序的方法。实际提供者将等于工厂函数的返回值。工厂功能可以依赖于几个不同的提供商,也可以保持完全独立。这意味着工厂可以接受参数,Nest将在实例化过程中解析并传递。此外,此函数可以异步
返回值。有更详细的解释。在必须动态
计算提供程序或解决异步
操作时使用它。
JS
const connectionFactory = {
provide: 'Connection',
useFactory: (optionsProvider: OptionsProvider) => {
const options = optionsProvider.get(
return new DatabaseConnection(options
},
inject: [OptionsProvider],
};
@Module{
providers: [connectionFactory],
})
export class ApplicationModule {}
提示
如果您的工厂需要其他提供程序,则必须在inject
数组中传递其标记。Nest将以相同的顺序将实例作为函数的参数传递。
导出定制提供商
为了导出自定义提供程序,我们可以使用令牌或整个对象。以下示例显示了一个令牌案例:
JS
const connectionFactory = {
provide: 'Connection',
useFactory: (optionsProvider: OptionsProvider) => {
const options = optionsProvider.get(
return new DatabaseConnection(options
},
inject: [OptionsProvider],
};
@Module{
providers: [connectionFactory],
exports: ['Connection'],
})
export class ApplicationModule {}
但是你也可以使用整个对象:
JS
const connectionFactory = {
provide: 'Connection',
useFactory: (optionsProvider: OptionsProvider) => {
const options = optionsProvider.get(
return new DatabaseConnection(options
},
inject: [OptionsProvider],
};
@Module{
providers: [connectionFactory],
exports: [connectionFactory],
})
export class ApplicationModule {}