返回

Reflections 依赖注入为装饰器注入新意

前端

在express 开发中,我们经常能看到这样的代码:

app.get('/user', (req, res) => {
  const userId = req.params.id;
  const user = await userService.findById(userId);
  res.json(user);
});

为了获取核心数据去写一些与业务逻辑无关的代码,数据一多的话,代码就会很冗杂。

有了 Nest.js 强力的装饰器,我们可以这样写:

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get(':id')
  async findById(@Param('id') userId: string) {
    const user = await this.userService.findById(userId);
    return user;
  }
}

把路由抽成一个类,从而更专注和具体的维护;路由参数使用装饰器捕获,直接拿到核心数据,这样代码可读性也变强了。

核心概念:依赖注入
Nest.js 利用了 TypeScript 的装饰器特性,把依赖注入的概念进一步发扬光大。装饰器可以被用来声明一个类的构造函数参数,并且自动完成依赖注入,在开发Nest.js应用程序时,我们可以使用依赖注入来减少代码的冗余和提高代码的可读性。

强大的装饰器和深层的抽象
Nest.js 自带了一些常用的装饰器,可以用来装饰控制器、服务、中间件等,从而让代码更加优雅和易于维护。装饰器通过 Reflect Metadata 来实现依赖注入,Reflect Metadata 是一个 JavaScript 标准,它允许我们存储和检索任意对象上的元数据。

Nest.js 的装饰器通过 Reflect Metadata 来存储依赖信息,然后在运行时自动完成依赖注入。这使得 Nest.js 的代码更加简洁和易于维护。

实际操作:实施装饰器依赖注入
比如说,我们现在有这么一个服务:

export class UserService {
  constructor(private readonly userRepository: UserRepository) {}

  async findById(userId: string) {
    return this.userRepository.findById(userId);
  }
}

如果我们想在控制器中使用这个服务,就可以通过装饰器来实现:

@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get(':id')
  async findById(@Param('id') userId: string) {
    const user = await this.userService.findById(userId);
    return user;
  }
}

在构造函数中,我们使用 @Inject() 装饰器来声明对 UserService 的依赖,然后在 Nest.js 启动时,Nest.js 会自动完成依赖注入。

总结
Nest.js 的装饰器和依赖注入是 Nest.js 的两大核心特性。装饰器让代码更加优雅和易于维护,依赖注入减少了代码的冗余和提高了代码的可读性。Nest.js 的装饰器通过 Reflect Metadata 来实现依赖注入,这使得 Nest.js 的代码更加简洁和易于维护。