Nest框架重要基础概念 => 提供者(Providers)
Provider:实例和服务
private:私有的
readonly:只读
@Injectable()
装饰器
用于将类标记为可注入的 Provider,可以通过依赖注入的方式管理和维护组件之间的依赖关系,提高了代码的可维护性和可测试性
import { Injectable } from '@nestjs/common';
// 表示该类可以被注入到其他组件中
@Injectable()
export class CatsService {
private readonly cats = ['Tom', 'Kitty', 'Garfield'];
findAll(): string[] {
return this.cats;
}
}
Provider
Provider 只是一个用 @Injectable()
装饰器注释的类
Provider 的作用是为应用程序中的其他组件提供服务或实
可以在应用中实现模块化开发,并且能够以模块为单位进行组件的管理和注入,提高了应用程序的可维护性和可扩展性。
举个例子:
// 定义服务方法,方便其他组件调用
import { Injectable } from '@nestjs/common';
@Injectable()
export class CatsService {
private readonly cats = ['Tom', 'Kitty', 'Garfield'];
findAll(): string[] {
return this.cats;
}
}
// 控制器中使用
import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
@Controller('cats')
export class CatsController {
// 依赖注入
constructor(private catsService: CatsService) {}
@Get()
findAll(): string[] {
// 调用服务中的方法
return this.catsService.findAll();
}
}
注册提供者
想要将服务注入到组件中,就必须在模块文件中编辑(下面是在主模块中进行的编辑)
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class AppModule {}
快速实现注册
要使用 CLI
创建服务类,只需执行 $ nest g service cats
命令
$ nest g service cats
服务
在service.ts
文件中,使用@Injectable()
装饰器,来装饰一个类
// cats.service.ts
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
向类的方法中,添加属性(使用的是构造函数注入的方式)
export interface Cat {
name: string;
age: number;
breed: string;
}
在控制器中使用
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Post()
// 异步
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
依赖注入
// 解析此依赖关系并将其传递给控制器的构造函数
constructor(private readonly catsService: CatsService) {}
Nest
将创建catsService
并返回一个实例来解析 CatsService
(或者,在单例的正常情况下,如果现有实例已在其他地方请求,则返回现有实例)
属性注入
import { Injectable, Inject } from '@nestjs/common';
@Injectable()
export class HttpService<T> {
@Inject('HTTP_OPTIONS')
private readonly httpClient: T;
}
在
HttpService
中,我们使用了@Inject('HTTP_OPTIONS')
装饰器来注入一个名为HTTP_OPTIONS
的依赖项。这意味着我们在创建HttpService
实例时,会自动注入一个名为HTTP_OPTIONS
的依赖项,并将其赋值给httpClient
属性。
// 使用
import { Controller, Get } from '@nestjs/common';
import { HttpService } from './http.service';
@Controller('cats')
export class CatsController {
constructor(private httpService: HttpService<any>) {}
@Get()
findAll(): any {
return this.httpService.httpClient.get('http://api.example.com/cats');
}
}
通过
httpService.httpClient.get()
方法发送了一个 GET 请求,以获取一组猫的数据
可选提供者
使用情况:一个类可能依赖于多个配置对象,但如果没有传递,则应使用默认值,provider
不会因为缺少配置导致错误。
要实现 provider 是可选的,在 constructor
的参数中使用 @Optional()
装饰器
import { Injectable, Optional, Inject } from '@nestjs/common';
@Injectable()
export class HttpService<T> {
constructor(
@Optional() @Inject('HTTP_OPTIONS') private readonly httpClient: T
) {}
}
HttpService
的构造函数接受一个httpClient
参数,该参数被标记为可选的(使用了@Optional()
装饰器)并且使用了@Inject('HTTP_OPTIONS')
装饰器来注入一个名为HTTP_OPTIONS
的依赖项。这意味着我们可以在创建HttpService
实例时向其传递一个httpClient
参数,或者使用默认的HTTP_OPTIONS
依赖项。
转载自:https://juejin.cn/post/7243987464296775735