【Nest】Providers 提供者

在 NestJS 中,Providers 用于定义、管理和注入各种服务和依赖。通常,Providers 是用来实现特定功能的服务、库或者工具类,在整个应用中可以被复用,并支持依赖注入。

1. Providers 的基本概念

在 NestJS 中,Providers 是被注入到其他组件中的类实例,例如 ServiceRepositoryHelper 等。通过使用 NestJS 的依赖注入机制,我们可以很方便地在一个组件中注入一个 Provider,而不用在组件中自己实例化依赖。每个 Provider 都可以在模块级别被定义和注册。

在 NestJS 中,Providers 的注册和声明通常是在模块文件(如 AppModule 或自定义模块)中完成的。

2. Providers 的定义

在 NestJS 中创建一个 Provider 时,通常步骤如下:

  1. 定义一个服务类。
  2. 在模块中将该服务注册为 Provider。
  3. 在其他类中注入该服务类,以使用其提供的功能。

3. 创建一个简单的 Provider

我们以一个简单的用户服务为例,展示如何创建和使用 Provider。

步骤 1:创建 UserService

UserService 中,我们定义一些管理用户的方法,例如获取用户列表或单个用户的信息。

// src/user/user.service.ts
import { Injectable } from '@nestjs/common';

@Injectable() // 1. 使用 @Injectable() 装饰器将 UserService 声明为 Provider
export class UserService {
  private users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
  ];

  findAll() {
    return this.users;
  }

  findOne(id: number) {
    return this.users.find(user => user.id === id);
  }
}
步骤 2:在模块中注册 Provider

我们需要在模块文件中将 UserService 注册为 Provider,这样其他组件才能使用它。NestJS 模块文件默认包含一个 providers 数组,用于声明模块的 Providers。

// src/user/user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';

@Module({
  providers: [UserService], // 2. 将 UserService 注册为 Module 的 Provider
  exports: [UserService],    // 3. 使用 exports 以便在其他模块中使用此 Provider
})
export class UserModule {}

通过将 UserService 添加到 providersexports 数组中,我们将它注册为一个可注入的 Provider,并允许其他模块访问。

这里也可以使用一个对象的方式进行 providers :

providers: [{
  provide:'User',
  userClass: UserService
}],

然后使用需要使用 @inject 装饰器:

@Inject("User") private readonly userService: UserService

此外,可以自定义注入值:

 providers: [{
   provide: "User",
   useClass: UserService
 }, {
   provide: "t1",
   useValue: ['t1', 'blg', 'tes']
 }
步骤 3:在其他服务中注入并使用 Provider

接下来,我们在另一个服务或控制器中使用 UserService。我们可以通过构造函数注入的方式使用 UserService

// src/app/app.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { UserService } from '../user/user.service';

@Controller('users')
export class AppController {
  constructor(private readonly userService: UserService) {} // 4. 通过构造函数注入 UserService

  @Get()
  findAll() {
    return this.userService.findAll(); // 调用 UserService 的 findAll 方法
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.userService.findOne(Number(id)); // 调用 UserService 的 findOne 方法
  }
}

4. 运行逻辑说明

当客户端访问 /users 路由时,AppController 将调用 UserServicefindAll 方法并返回所有用户数据。同样地,访问 /users/:id 时,将调用 findOne 方法并返回指定 ID 的用户。

通过这种方式,UserService 的实例可以在任何需要的地方注入和复用,而不需要重复创建实例。

5. Provider 的作用域

在 NestJS 中,Provider 的作用域包括三种:

  1. 默认作用域:Provider 在整个应用程序生命周期内是单例的。
  2. 请求作用域:Provider 在每个请求内是唯一的实例。这种方式适合处理和请求相关的状态。
  3. 瞬时作用域:每次注入时都会创建一个新实例。这适合需要短暂存在的对象。
@Injectable({ scope: Scope.REQUEST }) // 将作用域设置为请求作用域
export class UserService {
  // 你的服务逻辑
}

6. Provider 的工厂模式

除了直接定义类作为 Provider,NestJS 还支持使用工厂模式定义 Provider。工厂 Provider 是通过函数生成实例,特别适合初始化需要复杂配置的对象。

// src/app.providers.ts
import { Provider } from '@nestjs/common';

export const ConfigProvider: Provider = {
  provide: 'CONFIG',
  useFactory: () => ({
    appName: 'MyApp',
    version: '1.0.0',
  }),
};

这里使用的函数也可以使用异步函数。

在模块中注册该 Provider:

// src/app/app.module.ts
import { Module } from '@nestjs/common';
import { ConfigProvider } from './app.providers';

@Module({
  providers: [ConfigProvider], // 注册工厂 Provider
})
export class AppModule {}

在其他服务中注入:

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

@Injectable()
export class SomeService {
  constructor(@Inject('CONFIG') private config: any) {} // 通过 @Inject 注入工厂 Provider

  printConfig() {
    console.log(this.config); // 输出 { appName: 'MyApp', version: '1.0.0' }
  }
}

总结

在 NestJS 中,Providers 是创建、管理和注入服务、库的核心。通过使用 @Injectable() 装饰器、模块化管理和依赖注入,我们可以轻松创建可复用、易测试的服务层逻辑。同时,通过作用域和工厂模式,我们可以根据不同的场景和需求,灵活定义和配置 Providers,从而使应用更加灵活和模块化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秀秀_heo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值