当前位置: 首页 > 后端技术 > Node.js

Nestjs自译中文文档(三)

时间:2023-04-03 16:55:47 Node.js

Nestjs中文文档(三):ProvidersProvider是Nest的基本概念。许多基本的Nest类都可以被认为是提供者——服务、存储库、工厂、助手等。提供者的主要思想是它可以注入依赖项。这意味着对象之间可以创建各种关系,“连接”对象实例的功能可以在很大程度上委托给Nest运行时系统。提供者只是带有@Injectable()装饰器的类在上一章中,我们构建了一个简单的CatsController。控制器应该处理HTTP请求并将更复杂的任务委托给提供者。提供者只是普通的JavaScript类,在类声明之前带有@Injectable()装饰器由于Nest允许以更面向对象的方式设计和组织依赖项,因此我们强烈建议遵循SOLID的原则。提示:设计模式中的SOLID原则有单体原则、开闭原则、里氏代换原则、接口隔离原则、依赖倒置原则。前人总结说,遵循五个原则可以使程序解决紧耦合,使其更加健壮。服务service让我们从创建一个简单的CatsService开始。这个服务会负责数据的存储和检索(简称:服务负责存储和查询数据),是为catscocontroller设计的,所以适合定义为ForProvidersimport{Injectable}from'@nestjs/common';从'./interfaces/cat.interface'导入{Cat};@Injectable()exportclassCatsService{privatereadonlycats:Cat[]=[];创建(猫:猫){this.cats.push(猫);}findAll():Cat[]{返回this.cats;}}提示:要创建一个服务,只需嵌套gservicecats我们的CatsService是一个属性和一个带有两个方法的基类。唯一的新特性是它使用了@Injectable()装饰器。@Injectable()附加元数据,它告诉Nest这个类是一个NestProvider。顺便说一句,这个例子也使用了一个Cat接口,它可能看起来像这样:exportinterfaceCat{name:string;年龄:数字;breed:string;}现在我们有了一个检索猫的服务类,让我们在CatsController中使用它-cat.dto';从'./cats.import{CatsService}。service';import{Cat}from'./interfaces/cat.interface';@Controller('cats')exportclassCatsController{constructor(privatereadonlycatsService:CatsService){}@Post()asynccreate(@Body()createCatDto:CreateCatDto){this.catsService.create(createCatDto);}@Get()asyncfindAll():Promise{returnthis.catsService.findAll();}}CatsService通过类构造函数注入。注意私有只读语法的使用。这个参数允许我们在同一个地方立即声明和初始化catsService成员依赖注入嵌套是围绕一个通常称为“依赖注入”的强大设计模式构建的。我们建议阅读Angular官方文档中关于此概念的精彩文章。毕竟,Nest直接借鉴了Angular。在Nest中,由于TypeScript功能,管理依赖关系非常容易,因为它们仅按类型解析。在下面的示例中,Nest通过创建并返回CatsService的实例来解析catsService(或者,在单例的正常情况下,如果已在其他地方请求它,则返回现有实例)。此依赖项已解析并传递给控制器??的构造函数(或分配给指定的属性):constructor(privatereadonlycatsService:CatsService){}Scopedproviders通常具有与应用程序生命周期(“范围”)同步的生命周期。引导应用程序时,必须解析每个依赖项,因此必须实例化每个提供程序。同样,当应用程序关闭时,每个提供者都会被销毁。但是,也有一些方法可以使提供者的生命周期达到请求范围。您可以在此处阅读有关这些技术的更多信息。CustomProvidersNest有一个内置的IOC容器(IOC:InversionofControl)来解析提供者之间的关系。IOC底层的依赖注入功能其实远比我们目前所描述的要强大得多。@Injectable()装饰器只是冰山一角,并不是定义Provider的唯一方式。事实上,您可以使用纯文本值、类以及异步或同步工厂。此处有更多示例OptionalProviders有时,您可能有不一定要解决的依赖项。例如,你的类可能依赖于一个配置对象,但如果没有传递配置对象,应该使用默认值。在这种情况下,依赖项变为可选,因为缺少配置提供程序不会导致错误。要指示Provider是可选的,请在构造函数的签名中使用@Optional()装饰器。@Injectable()exportclassHttpService{constructor(@Optional()@Inject('HTTP_OPTIONS')privatereadonlyhttpClient:T){}}Property-basedinjection到目前为止我们使用的技术被称为construction-basedFunction注入,因为Provider是通过构造函数注入的。基于属性的注入在某些非常特殊的情况下可能很有用。例如,如果您的顶级类依赖于一个或多个Provider,那么通过在构造函数的子类中调用super()将它们一路向下传递可能会很乏味。为避免这种情况,可以在属性级别使用@Inject()装饰器。import{Injectable,Inject}from'@nestjs/common';@Injectable()exportclassHttpService{@Inject('HTTP_OPTIONS')privatereadonlyhttpClient:T;}如果你的类没有扩展其他Provider,那么Constructor应始终使用基于注入。提供者的注册现在我们已经定义了一个提供者(CatsService),并且我们有一个该服务的消费者(CatsController),我们需要向Nest注册该服务,以便它可以执行注入。我们可以通过编辑模块文件(app.module.ts)并将服务添加到@Module()装饰器的提供程序数组来完成此操作。从'@nestjs/common'导入{Module};从'./cats/cats.controller'导入{CatsController};从'./cats/cats.service'导入{CatsService};@Module({控制器:[CatsController],providers:[CatsService],})exportclassAppModule{}Nest现在可以解析CatsController类的依赖关系。这是我们现在的目录结构:(以类似JSON的方式表达,希望可以理解){src:{cats:{dto:{create-cat.dto.ts},interfaces:{cat.interface.ts},cats.service.ts,cats.controller.ts},app.module.ts,main.ts}}