- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
上篇文章我们学习了如何使用 nest-cli 来快速生成一个 NestJS 后端项目,当我们打开编辑器查看代码时,会发现整个代码风格有点类似JAVA的 spring 框架,并且你会发现一些 service 类在 controller 控制器的 constructor 中注入后,可以不需要手动 new 就可以直接使用该类对应的实例方法.
比如:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('/hello')
get(): string {
return this.appService.getHello();
}
}
这其实就是 Nest 依赖注入与控制反转,目的主要是方便代码之间的解耦从而减少维护成本.
这两个概念不要搞混了,IOC其实是面向对象编程中的一种设计模式,而DI则是为了实现IOC的一种技术.
比如,我们有两个类,它们之间存在耦合关系,我们一般会这样写:
// A.ts
class A {
name: string
constructor(name: string) {
this.name = name
}
}
// B.ts
class B {
age: number
name: A
constructor(age: number) {
this.age = age
this.name = new A('南玖')
}
}
// main.ts
const b = new B(18)
console.log(b)
当我们遇到类与类之间存在依赖关系时,一般会直接在类的内部创建依赖对象,这样就会导致各个类之间形成耦合,并且这种关系会随着依赖关系越来越复杂从而耦合度也会越来越高,最终造成代码的难以维护.
为了解决上面代码带来的耦合性问题,我们可以使用IOC容器来进行管理 。
// container.ts
export class Container {
modules = new Map()
// 注册实例
provide(key: string, clazz: any, argvs: Array<any>) {
this.modules.set(key, {clazz, argvs})
}
// 获取实例
get(key: string) {
const {clazz, argvs} = this.modules.get(key)
return Reflect.construct(clazz, argvs)
}
}
这里的 Reflect.construct 是为了帮我们实例化一个对象.
以上就是容器化思路,统一管理,可以实现类与类之间的解耦.
依赖注入是一种控制反转 IOC(inversion of control) 技术,就是你可以把对象或依赖的实例化交给 IOC 容器去处理,在 NestJS 中这个容器就是 NestJS 的运行时系统。当需要一个对象实例的时候,我们不需要自己手动 new xxxClass() ,只需要在合适的地方对类进行注册,在需要用到的地方直接注入,容器将为我们完成 new 的动作 。
在 Nest 中使用依赖注入一般有以下三步:
使用 @Injectable 装饰器来声明一个类,它表示该类可以由 Nest 的 IOC 容器管理 。
// app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello nanjiu';
}
}
这是依赖注入的地方,一般是在类的构造函数 constructor 中注入,只有完成注入后才可以使用 。
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('/hello')
get(): string {
return this.appService.getHello();
}
}
官方把 appService 称为 token , NestJS 会根据这个 token 在容器中找到第1步中声明的类(这个对应关系将在第三步中进行关联注册),从而提供对应的实例,这里的实例全局唯一,只有1个!在第一次需要该实例的时候, Nest 会 new 一个出来,而后会缓存起来,后序如果其它地方也注入了这个依赖,那 Nest 会从缓存中拿到之前 new 出来的实例供大家使用.
依赖注入后还需要在 Module 中进行关联 。
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Nest 会根据所有注入的依赖关系生成一个依赖关系图,就有点类似我们使用 import 引入各个模块时也会生成一个复杂的依赖关系图。这里 AppController 中依赖了 AppService ,如果 AppService 中还依赖其它东西也会一并放到 Nest 构建的依赖关系图中, Nest 会从下到上按照依赖顺序构建出一整张依赖关系图保证所有的依赖关系正常运作.
最后此篇关于【NestJS系列】DI依赖注入与IOC控制反转的文章就讲到这里了,如果你想了解更多关于【NestJS系列】DI依赖注入与IOC控制反转的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我开始认真考虑使用 IoC 容器会引发创建过度设计的解决方案(至少它会促使我尝试使用各种不必要的功能:)。 是时候将我的“IoC”反模式列表与社区列表同步了。 我短暂的经验告诉我们,在启动时每个应用程
我一直在阅读有关控制反转框架的内容,而我只是在玩弄这个问题:“我到底为什么需要一个框架来做到这一点?” 不要误解我的问题...该模式是我们程序员经常使用的,但是...一个功能齐全的框架可以做到这一点?
想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。 我正在尝试确定是否需要付出额外的努力来封装我的 IoC 容器。经验告诉我,我应该
有人建议我,在使用 IOC 容器时,我应该改变这个: class Foobar: IFoobar, IDisposable {}; 进入这个: interface IFoobar: IDisposab
《畜牧代码》播客第 68 期有人,http://herdingcode.com/herding-code-68-new-year-shenanigans/ ,表示 IOC 容器不适合使用 Python
我们正在使用 NInject 框架在我们的应用程序中实现 IoC/DI。我们有具有内部方法的内部类。要实现 IoC/DI,我们必须提取接口(interface)。但是如果我们在一个内部类中只有内部方法
Spring IOC 相关接口分析 1.BeanFactory Spring 中 Bean 的创建是典型的工厂模式,这一系列的 Bean 工厂,即 IOC 容器,为开发者管理对象之间的依赖关系提供了很
MEF is not an IoC container .不过好像是差不多 一个 IoC 容器。似乎我可以很容易地让 MEF 表现得像一个 IoC 容器(见下面的例子),而且让 MEF 成为一个完整的
只是想继续了解 IOC 的原则。 Q1:静态方法 - 具有静态辅助方法的实用程序类是否应该与 IOC 连接? 例如,如果我有一个带有许多静态方法的 HttpUtils 类,我是否应该尝试通过 IOC
众所周知,在asp.net Startup 类中有一个方法ConfigureServices,我们可以添加自定义服务。服务通过依赖注入(inject)提供。 ASP.NET Core includes
所以..我一直在深入研究 IoC 容器和服务定位器。 我认为 IoC 容器是 IoC 容器,而不是服务定位器,因为 您使用它的方式。您将服务定位器传递给需要依赖项的类,然后通过容器检索依赖项。另一方面
阅读许多有关这三个成语之间差异的帖子。但是比较困惑,然后我遇到了这篇文章: http://martinfowler.com/articles/injection.html 只是想看看我是否做对了。如果
我正在寻找用于 asp.net webapi 的 ioc 容器。我们正在寻找的几个关键功能如下 自定义生命周期 对网络请求生命周期的内置支持 在管理依赖项注册方面与 Web API 的良好集成。 最佳
我很难跟随 FP。当人们说“更惯用的风格”时,我必须明白:99% 的 Java 库不适用于 Kotlin 和 Scala 的 FP 惯用风格,对吧?好吧,我需要 Spring Boot 来快速启动 V
目录 1、Spring 1.1、简介 1.2、优点 1.3、组成 1.4、扩展 2、IO
重要提示:请注意,我并不是说单例具有私有(private)构造函数和静态实例变量(或有人建议使用静态类),而是单例在应用程序生命周期内从控制容器的反转返回相同的实例。 许多容器默认使用较短的生命周期。
Closed. This question needs to be more focused。它当前不接受答案。 想要改善这个问题吗?更新问题,使它仅关注editing this post的一个问题。
松耦合当然很棒,但我经常想知道使用 IoC 容器(例如 CaSTLe Windsor)动态连接的开销对紧耦合系统有什么影响? 我知道详细的答案将取决于 IoC 的用途,但我真的只是想了解 IoC 工作
我正在努力让 IOC 在远程处理场景中工作。我将我的应用程序服务器设置为发布通过 XML 配置的服务(SingleCall)。 众所周知,这就像这样: RemotingConfiguration.Co
我使用 IoC (DI) 方法并且通常有参数,这些参数由最低层(数据库层等)从配置设置(即连接字符串、静态值等)中读取。最好的方法是什么? 直接在这个最底层读取,即: string sendGridA
我是一名优秀的程序员,十分优秀!