10_nest.js 提供者

简介: 10_nest.js 提供者

写在前面:在nest.js中,底层服务被封装在service里,我们需要在controller中调用它们,但是在此之前为了做控制反转,我们需要先使用module把依赖收集起来并提供给controller,最后在controller中注册(注入)依赖供后续调用。

自定义依赖名称

先来看一个基本的使用语法糖的例子(没有自定义依赖名称):

import { UserService } from './user.service';
@Module({
  controllers: [UserController],
  providers: [UserService]  // 依赖在这里提供
})
// 不需要额外import
@Controller('user')
export class UserController {
  /* 依赖在这一行注入,由于使用的是语法糖,直接写成userService:UserService的形式就行了,无需@Inject() */
  constructor(private readonly userService: UserService) {}
// 以下代码不重要不用管
  @Get()
  findAll() {
    return this.userService.findAll();
  }
}

但其实,module.ts里的provide的原始写法是这样子的

@Module({
  controllers: [UserController],
  /* 这里的写法变了 */
  providers: [
    {
      provide: 'xiaoman',
      useClass: UserService,
    },
  ],
})

在这种写法下,controller.ts里构造器注入的依赖需要多加一个@Inject(<string>)装饰器,字符串的内容就是provider的内容

@Controller('user')
export class UserController {
  constructor(@Inject('xiaoman') private readonly userService: UserService) {}
  @Get()
  findAll() {
    return this.userService.findAll();
  }
}

以上,我们就完成了自定义依赖名称的过程

自定义注入值

除了自定义依赖外,我们也可以自定义注入值,这在所有服务都需要依赖同一个值的时候非常好用

@Module({
  controllers: [UserController],
  providers: [
    {
      provide:'JD',
      useValue:['JD','TB']
    }
  ],
})

同样的,这个依赖需要被注入到controllers.ts中

@Controller('user')
export class UserController {
  constructor(
    // 使用Inject()装饰器注入对应的值
    @Inject('JD') private shopList: string[],
  ) {}
  @Get()
  findAll() {
    return this.shopList;
  }
}

工厂模式

如果服务间存在依赖,可以使用工厂模式

import { UserService3 } from './user.service3';
@Module({
  controllers: [UserController],
  providers: [
    {
      provide: 'xiaoman',
      useClass: UserService,
    },
    {
      provide: 'Test',
      // 必须要先inject才能将依赖写进useFactory
      inject: ["xiaoman"],
      useFactory(UserService:UserService){
        // 在这里将依赖传给UserService3的构造函数
        return new UserService3(UserService)
      }
    },
  ],
})
import { Inject, Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Injectable()
export class UserService3 {
  /* 注入Test依赖 */
  constructor(@Inject('Test') private readonly test){}
  create(createUserDto: CreateUserDto) {
    return 'This action adds a new user';
  }
  findAll() {
    // 调用依赖中的方法
    return this.test.findAll();
  }
  findOne(id: number) {
    return `This action returns a #${id} user`;
  }
  update(id: number, updateUserDto: UpdateUserDto) {
    return `This action updates a #${id} user`;
  }
  remove(id: number) {
    return `This action removes a #${id} user`;
  }
}
import { UserService3 } from './user.service3';
@Controller('user')
export class UserController {
  constructor(
    // 注入Test依赖,这个依赖的本质是注入了UserService服务的UserService3的实例对象
    @Inject('Test') private test: UserService3,
  ) {}
  @Get()
  findAll() {
    return this.test.findAll();
  }
}

异步工厂模式

useFactory支持异步模式

@Module({
  controllers: [UserController],
  providers: [
    // 准备注入Test的依赖
    {
      provide: 'xiaoman',
      useClass: UserService,
    },
    // 注入controller的依赖
    {
      provide: 'Test',
      inject: ['xiaoman'],
      // 此处使用异步逻辑。注意返回的内容是一段字符串,因此没有方法
      async useFactory(UserService: UserService) {
        return await new Promise((r) => {
          setTimeout(() => {
            r(UserService.findAll());
          },2000);
        });
      },
    },
  ],
})

将依赖注入controller与前端交互

@Controller('user')
export class UserController {
  constructor(
    @Inject('Test') private test: UserService,
  ) {}
  @Get()
  findAll() {
    return this.test;
  }
}

以上,当我们刷新页面后,过两秒钟页面才会更新

怎样?是不是感到非常懵逼?没关系,我们来理清一下service、module和controller之间的关系

  1. Service:提供底层Web服务(类),是方法的实际提供者,拥有装饰器@Injectable
  2. Module:将服务类从Service中导入(需要import),实例化后将其提供给controller。在IOC体系中充当中间管理者,拥有装饰器@Module
  3. Controller:一切服务在此调用(不需要import,只要用@Inject(<string>)注入依赖即可使用),前端访问接口返回什么内容全部在此处决定,需要注意的是如果在Module里使用语法糖模式则无需额外@Inject()
目录
相关文章
|
30天前
|
JavaScript 前端开发
08_nest.js控制器详解
08_nest.js控制器详解
30 4
|
8月前
|
缓存 Shell API
一文带你掌握nest.js访问静态资源
一文带你掌握nest.js访问静态资源
一文带你掌握nest.js访问静态资源
|
11月前
快速入门nest.js(7/10)--应用配置
然后,你就可以像下面的方式使用对应的变量值了,注意这里所有的变量值都是字符串,而port要求的是数字,所以我们还需要进行一个转换。
120 0
|
30天前
11_nest.js模块
11_nest.js模块
24 0
|
30天前
|
中间件
12_nest.js中间
12_nest.js中间
39 1
|
8月前
|
API 网络架构
初识nest.js的controller(入门)
初识nest.js的controller(入门)
|
11月前
|
数据库
Nest.js学习笔记(五)
本节记录Nest.js工程相关知识
61 0
|
11月前
|
JavaScript
Nest.js学习笔记(三)
本节记录TypeScript的若干装饰器,仅做示范,如需详细了解可自行移步官方文档
55 0
|
11月前
|
容器
Nest.js学习笔记(二)
本节记录依赖倒置、控制反转、依赖注入相关内容
57 0
|
11月前
|
API
Nest.js学习笔记(六)
本节记录Restful风格Api的介绍以及使用Nest.js做了一个简单的版本控制
115 0