定制供应商

定制供应商

当您可能希望将某些内容直接绑定到控件容器的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也会注入所提供的类(DevelopmentConfigServiceProductionConfigService)的实例。

使用工厂

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 {}