背景
最近项目需要到一个基于事件驱动的一些业务模块,就封装一下类似@nestjs/bull一样的API去进行事件注册和触发,减少了一定的代码量。
通过Nest Core的功能去完成全局扫描metadata
通过@nestjs/core,我们可以找到相应框架实现的功能和工具,去完成我们需要写业务逻辑前的工作
DiscoveryService —— 扫描所有app module注册到的controllers和services
首先我们需要扫描所有的controller和service,通过DiscoveryService可以实现,伪代码如下:
// explorer.service.ts
import {
Injectable } from '@nestjs/common';
import {
DiscoveryService} from '@nestjs/core';
@Injectable()
export class AccessorService {
constructor(
private readonly discoveryService: DiscoveryService
) {
}
run() {
const providers = this.discoveryService.getProviders();
const controllers = this.discoveryService.getControllers();
// ...
}
}
那么调用这些方法返回的是什么?从类型定义上看,是一个InstanceWrapper,主要是在nestjs对controller和service注入到module的时候,对class实例后的对象封装了一层wrapper
MetadataScanner —— 扫描出有Metadata的类方法
然后再去遍历我们定义的decorator和metadata,这时候就需要MetadataScanner
// explorer.service.ts
import {
Injectable } from '@nestjs/common';
import {
DiscoveryService} from '@nestjs/core';
import {
MetadataScanner } from '@nestjs/core/metadata-scanner';
@Injectable()
export class AccessorService {
constructor(
private readonly discoveryService: DiscoveryService,
private readonly metadataScanner: MetadataScanner,
) {
}
run() {
const providers = this.discoveryService.getProviders();
const controllers = this.discoveryService.getControllers();
[...providers, ...controllers]
.filter(wrapper => wrapper.isDependencyTreeStatic())
.filter(wrapper => wrapper.instance)
.forEach((wrapper: InstanceWrapper) => {
const {
instance } = wrapper;
const prototype = Object.getPrototypeOf(instance);
this.metadataScanner.scanFromPrototype(
instance,
prototype,
(methodKey: string) => {
console.
Nest.js实战:全局扫描metadata实现

本文介绍如何利用Nest.js核心功能,通过DiscoveryService和MetadataScanner扫描应用程序中的controllers和services的metadata。详细讨论了如何获取和使用metadata来构建事件驱动的业务模块,提供了一种减少代码量的方法。
最低0.47元/天 解锁文章
459

被折叠的 条评论
为什么被折叠?



