用户登录

在 AppService 这个服务里面,通过构造方法的参数属性,注入了一个依赖,就是这个 LoggerService。 Nest 框架在创建类的实例的时候,会检查类的依赖,发现有依赖就会先去解决类的依赖问题。

比如在创建 AppService 这个服务类的实例的时候,Nest 发现它有一个依赖,是 LoggerService,在 AppService 所属的模块里面,配置了一下这个 Provider,名字是 LoggerService,对应的东西是一个类,类的名字是 LoggerService。

这样 Nest 就会到它的 IoC Container 那里查询有没有 LoggerService 实例。如果还没有,就会创建一个,如果这个实例在 IoC Container 里已经存在了,就直接返回这个实例。

design:paramtypes

确定类具体需要的依赖是什么,Nest 会用到 TypeScript 语言提供的几样东西。在类的上面,如果使用了装饰器装饰了一下,这个类在编译成 JavaScript 的时候,会保留类的构造方法参数的类型信息。

比如这个 AppService 类,用了 @Injectable 装饰器,所以这个类被编译成 JavaScript 的时候,也就会保留它的构造方法参数的类型相关的信息。这里就是 LoggerService。

我们可以打开编译之后的 AppService 检查一下,在 dist 目录的下面,打开 app.service.js,它就是编译成 JavaScript 之后的 app.service.ts 文件。

因为在 AppService 这个类的定义上面用了一个装饰器,所以把这个类编译成 JavaScript 以后,就会保留类的构造方法参数的类型信息。

__metadata 这个方法会添加一外额外的元数据,这里添加了一个叫 design:paramtypes 的元数据,它的值就是类的构造方法参数的类型信息。这个值是个数组,数组里面有个项目,就是 LoggerService。

这样 Nest 可以使用 TypeScript 提供的 Reflect 接口,就可以得到在 AppService 上添加的 design:paramtypes 的值。根据返回的这个值,Nest 就可以确定怎么样解决这个类依赖的东西。

再试一下,可以去掉 AppService 上用的这个装饰器,然后回到编译之后的 AppService,你会发现,代码简单了很多。因为类的定义上面没有使用装饰器,所以编译之后的代码里面,也就没有构造方法参数的类型信息,这样 Nest 也就没有办法解决这个类的依赖。

所以如果想在类里面注入依赖,这个类的定义的上面就必须得用某个装饰器装饰。在 Provider 上面,就用这个 @Injectable 装饰器。AppController 这个控制器里也需要注入一个依赖,这个控制器类的定义上面,用了一个 @Controller 装饰器,所以这个类被编译成 JavaScript 以后,也会保留它的构造方法参数的类型信息。

理解 Nest 框架依赖注入的内部机制《 企业级应用架构:依赖注入 》

统计

14696
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点