nestjs之定义provider以及inject使用的几种方式

在NestJS中可以以多种方式自定义Providers。以下是一些常见的方法:

1. 值提供者(Value Providers)

值提供者用于提供一些硬编码的值,例如配置对象或常量。这类提供者通过 useValue 关键字来指定要注入的值。

使用过程

  1. 在你的模块中定义一个值提供者。
  2. 使用 provide 属性来指定令牌(通常是一个字符串或符号)。
  3. 使用 useValue 属性来提供一个硬编码的值。

示例

import { Module } from '@nestjs/common';

@Module({
  providers: [
    {
      provide: 'API_KEY',
      useValue: '12345-ABCDE',
    },
  ],
})
export class AppModule {}

2. 类提供者(Class Providers)

类提供者用于将类实例作为依赖注入。这是最常见的提供者类型,通常用于服务类。

使用过程

  1. 创建一个服务类。
  2. 在模块的 providers 数组中使用该类。
  3. 使用 provide 关键字指定一个令牌,并使用 useClass 来指定类。

示例

import { Module } from '@nestjs/common';

class MyService {
  // 服务逻辑
}

@Module({
  providers: [
    {
      provide: 'MyService',
      useClass: MyService,
    },
  ],
})
export class AppModule {}

3. 工厂提供者(Factory Providers)

工厂提供者通过工厂函数来创建提供者实例。这种方式适用于需要动态创建依赖项的场景。

使用过程

  1. 定义一个工厂函数,该函数返回提供者的实例。
  2. 在模块的 providers 数组中使用这个工厂函数。
  3. 使用 provide 关键字指定一个令牌,并使用 useFactory 来指定工厂函数。

示例

import { Module } from '@nestjs/common';

@Module({
  providers: [
    {
      provide: 'ASYNC_CONNECTION',
      useFactory: async () => {
        const connection = await createConnection();
        return connection;
      },
    },
  ],
})
export class AppModule {}

4. 异步提供者(Async Providers)

异步提供者是工厂提供者的一个变种,允许在提供者实例化之前执行一些异步操作。

使用过程

  1. 创建一个异步的工厂函数。
  2. 在模块的 providers 数组中使用这个异步函数。
  3. 使用 provide 关键字指定一个令牌,并使用 useFactory 来指定异步工厂函数。

示例

import { Module } from '@nestjs/common';

@Module({
  providers: [
    {
      provide: 'ASYNC_CONNECTION',
      useFactory: async () => {
        const connection = await createConnection();
        return connection;
      },
    },
  ],
})
export class AppModule {}

5. 别名提供者(Alias Providers)

别名提供者用于为已存在的提供者创建一个别名。

使用过程

  1. 定义一个服务或提供者。
  2. 创建一个别名提供者,并使用 useExisting 指向现有的服务或提供者。

示例

import { Module } from '@nestjs/common';

class ActualService {
  // 实际服务的逻辑
}

@Module({
  providers: [
    ActualService,
    {
      provide: 'AliasService',
      useExisting: ActualService,
    },
  ],
})
export class AppModule {}

6. 多提供者(Multi Providers)

多提供者用于在一个令牌下注册多个提供者,通常用于创建插件系统或聚合相同类型的服务。

使用过程

  1. 在模块的 providers 数组中定义多个提供者。
  2. 所有这些提供者使用相同的令牌,并将 multi 属性设置

true

示例

import { Module } from '@nestjs/common';

class MyService {
  // 服务逻辑
}

class AnotherService {
  // 另一个服务的逻辑
}

@Module({
  providers: [
    {
      provide: 'MY_SERVICE',
      useClass: MyService,
      multi: true
    },
    {
      provide: 'MY_SERVICE',
      useClass: AnotherService,
      multi: true
    },
  ],
})
export class AppModule {}

以上是 NestJS 中六种自定义提供者的具体使用过程。这些提供者可以灵活地应用于各种场景,满足不同的开发需求。
在 NestJS 中,inject 选项用于自定义 provider 时,用来指定依赖项的注入。这是在创建复杂 provider 或者在提供 provider 时需要某些依赖项时非常有用的特性。inject 选项通常与 useFactoryuseClass 结合使用。

使用 useFactoryinject

当使用工厂函数 (useFactory) 定义 provider 时,inject 选项可以指定哪些依赖项需要被注入到这个工厂函数中。这些依赖项可以是其他已注册的 provider、常量值等。

例子:

假设有一个配置服务 (ConfigService) 和一个日志服务 (LoggerService),我们需要在工厂函数中使用这些服务来配置另一个服务。

import { Module, Injectable } from '@nestjs/common';

@Injectable()
class ConfigService {
  get(key: string): string {
    // 假设是从某个配置源获取配置
    return 'some_value';
  }
}

@Injectable()
class LoggerService {
  log(message: string) {
    console.log(message);
  }
}

// 使用工厂函数创建 provider
@Module({
  providers: [
    ConfigService,
    LoggerService,
    {
      provide: 'CustomService',
      useFactory: (configService: ConfigService, loggerService: LoggerService) => {
        const value = configService.get('some_key');
        loggerService.log(`配置值:${value}`);
        // 根据配置创建并返回实例
        return new SomeService(value);
      },
      inject: [ConfigService, LoggerService], // 指定要注入的服务
    },
  ],
})
export class AppModule {}

使用 useClassinject

虽然 useClass 通常不需要 inject 选项,因为 NestJS 可以自动处理类的依赖注入,但在某些高级场景下,你可能需要显式地指定依赖项。这通常用于动态模块或更复杂的依赖注入场景。

例子:

假设有一个复杂的场景,其中一个类依赖于动态决定的服务。

import { Module, DynamicModule } from '@nestjs/common';

class ComplexService {
  constructor(private dynamicService: any) {}

  // ...
}

@Module({})
export class ComplexModule {
  static register(dynamicProvider): DynamicModule {
    return {
      module: ComplexModule,
      providers: [
        {
          provide: ComplexService,
          useClass: ComplexService,
          inject: [dynamicProvider.provide], // 显式指定依赖项
        },
        dynamicProvider,
      ],
      exports: [ComplexService],
    };
  }
}

在这个例子中,ComplexService 的实例化依赖于动态提供的服务。通过使用 useClassinject,我们能够在模块动态注册时灵活指定依赖项。

这两种方式展示了如何使用 inject 选项来注入依赖项,从而在 NestJS 中创建更灵活和动态的 provider。

你可能感兴趣的:(nestjs原理,javascript,前端)