Nest.js学习笔记(九)

简介: 本节记录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()装饰器,字符串的内容就是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()注入依赖即可使用),前端访问接口返回什么内容全部在此处决定,需要注意的是如果在Module里使用语法糖模式则无需额外@Inject()
相关文章
|
2月前
|
JavaScript 前端开发 API
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
|
1月前
|
JavaScript 前端开发
【干货分享】JavaScript学习笔记分享
【干货分享】JavaScript学习笔记分享
57 0
|
2月前
|
Web App开发 前端开发 JavaScript
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的云的学习笔记系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的云的学习笔记系统附带文章源码部署视频讲解等
41 0
|
6月前
|
移动开发 JavaScript 前端开发
webgl学习笔记3_javascript的HTML DOM
webgl学习笔记3_javascript的HTML DOM
65 0
webgl学习笔记3_javascript的HTML DOM
|
6月前
|
JavaScript 前端开发 Java
webgl学习笔记2_javascript基础快速学习
webgl学习笔记2_javascript基础快速学习
51 0
|
6月前
|
前端开发 JavaScript API
JavaScript学习笔记(一)promise与async
JavaScript学习笔记(一)promise与async
|
6月前
|
存储 JavaScript
【ES6系列第二篇】适用JS初学者的Set对象和Map对象学习笔记
【ES6系列第二篇】适用JS初学者的Set对象和Map对象学习笔记
49 0
|
存储 JavaScript 前端开发
【js】函数概述学习笔记(8)
【js】函数概述学习笔记(8)
43 0
|
存储 JavaScript
【js】数组学习笔记(7-2)
【js】数组学习笔记(7-2)
66 0
下一篇
无影云桌面