上文Provider中提到,将某一类特定功能最终包装到一个模块(Module)中,每个Nest都至少要有一个Module。每个模块类必须用@Module装饰器加上原数据(Metadata)来组织应用程序模块。

@Module装饰器

@Module装饰器接受一个对象参数,在Nest源码中是**ModuleMetadata**接口,它有四个字段,且均是数组类型,分别是:

通过以上四种类型的设定,Nest的IoC才能够准确识别需要组装(注入和被注入)各种依赖关系,同时实现一定程度的共享。

SOLID原则

SOLID指面向对象编程中的五项基本原则。应用这些原则,可以提升程序的可维护行和扩展性,同时也让大规模协作开发变得可能。表格源自WiKi:

字母 指代 概念
S 单一功能原则 认为对象应该仅具有一种单一功能的概念。
O 开闭原则 认为“软件体应该是对于扩展开放的,但是对于修改封闭的”的概念。
L 里氏替换原则 认为“程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的”的概念。参考契约式设计
I 接口隔离原则 认为“多个特定客户端接口要好于一个宽泛用途的接口”的概念。
D 依赖反转原则 认为一个方法应该遵从“依赖于抽象而不是一个实例” 的概念。 依赖注入是该原则的一种实现方式。

模块的设计遵循SOLID原则。另外,在Nest中:一组功能也会被归类到一个文件夹中,同时体现在程序文件名的前缀上。

模块共享

默认情况下,Nest使用的都是单例模式,一个Serivce也可以被多个Module导入使用。有心的同学可能已经发现了,在聊Provider时,即便是没有**UserModule,照样也可以在UserController中使用AppService**,那么将这个套路稍加推广,一定也可以在需要使用某个Provider的Module直接引入相关文件。我们在项目中追加一个UserModule


nest g mo user

内容如下:


@Module({
  controllers: [UserController],
  providers: [AppService],
})
export class UserModule {}

还需要修改app.module,引入user.module


@Module({
  imports: [UserModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}