You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
IoC:Inversion of Control (IoC) 是软件工程(software engineering)中的一种编程原则(programming principle),在面向对象编程或其他编程范式中得到应用。IoC inverts the flow of control as compared to traditional control flow。
Software frameworks, callbacks, schedulers, event loops, dependency injection, and the template method are examples of design patterns that follow the inversion of control principle, although the term is most commonly used in the context of object-oriented programming.
Inversion of control is sometimes facetiously referred to as the "Hollywood Principle: Don't call us, we'll call you".
前言
SOLID
在面向对象编程(object-oriented computer programming)中,SOLID 是五个设计原则(design principles)的缩写。
五个原则分别是:
因此,DIP:Dependency inversion principle,是面向对象编程中的设计原则之一,通过共享抽象解耦高层和低层的关系。
IoC
Inversion of control is sometimes facetiously referred to as the "Hollywood Principle: Don't call us, we'll call you".
控制反转有时被戏称为好莱坞原则: 不要打电话给我们,我们会打给你。
反转:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;
在面向对象编程中,有几个基本的方式可以实现 IoC:
所以,DI(dependency injection)是面向对象编程中 IoC 的一种实现的方式。
IoC 容器:依赖注入的框架,用来映射依赖,管理对象创建和生存周期(DI框架)。
InversifyJS 介绍
InversifyJS 是一个强大的、轻量级的 IoC 容器,使用 TS 编写,可用于构建 JS/Node 应用。InversifyJS 使用 class constructor 来定义和注入依赖,API 设计简单友好,方便你使用 OOP 和 IoC 的最佳编程实践。
JavaScript 现在支持基于类的继承的面向对象(OO)编程。这些特征是伟大的,但事实是,他们也是危险的。
我们需要一个好的 OO 设计(SOLID、复合重用(Composite Reuse)等)来保护我们自己免受这些威胁。问题是面向对象的设计是困难的,这正是我们创建 inversion.js 的原因。
InversifyJS 的开发为了实现 4 个目标:
InversifyJS 需要现代的 JavaScript engine 支持:
基础概念
Container
容器本身就是一个类实例,而 inversify 要做的就是利用这么一个类实例来管理诸多别的类实例,而且依靠一套有序的方法实现。
容器本身还有父容器和子容器的概念,所以 Container 对象有一个字段 parent 来表示,这样可以做到继承。这个概念在使用Container.resolve 的时候有用到。
Scope
在 inversify.js 中,或者说是在 IoC 的概念中存在一个叫做 scope 的单词,它是和 class 的注入关联在一起的。一个类的注入 scope可以支持以下三种模式:
Transient:每次从容器中获取的时候(也就是每次请求)都是一个新的实例
Singleton:每次从容器中获取的时候(也就是每次请求)都是同一个实例
Request:社区里也成为Scoped模式,每次请求的时候都会获取新的实例,如果在这次请求中该类被require多次,那么依然还是用同一个实例返回。
Scope可以全局配置,通过defaultScope参数传参进去,也可以针对每个类进行区别配置,使用方法是:
TS 的装饰器
参考:TS - 装饰器
Reflect Metadata
实现架构
Inversify在真正解析一个依赖之前会执行三个必须的操作(另外包含两个可选操作):
inversify的绑定过程
除了to语法,其余的语法其实都是在往Binding这个类实例的属性赋值。
就是下面这些属性:
所有的入口都是指向BindingToSyntax这个类,再往外衍生出各种when语法。
上面的所有绑定除了最后一个,都会返回一个when/on/in语法供开发者往绑定里面加入更多的元素,比如一些限制条件、指定生效scope等等,接下来的演变如下图,只有to和toDynamicValue才支持in操作,所有其走的路线是inWhenOn,其余的都是WhenOn路线:
使用
支持 Symbols
在非常大的应用程序中,使用字符串作为将由 inversionjs 注入的类型的标识符,可能会导致命名冲突。支持并推荐使用 Symbols 而不是字符串文字。
使用步骤
声明依赖的 Demo 如下,具体可以参考 Readme。
也可以使用 property injection 代替 constructor injection ,这样就不用声明构造函数。
创建和配置容器:
使用
示例
Angular
在 Angular 2+ 的版本中,控制反转与依赖注入便是基于此实现,现在,我们来实现一个简单版:
参考
The text was updated successfully, but these errors were encountered: