数栈技术分享:前端小姐姐和你聊聊IOC中依赖注入那些事 (Dependency inject)
Part1: What is Dependency injection
依赖注入定义为组件之间依赖关系由容器在运行期决定,形象的说即由容器动态的将某个依赖关系注入到组件之中在面向对象编程中,我们经常处理的问题就是解耦,控制反转(IoC)就是常用的面向对象编程的设计原则,其中依赖注入是控制反转最常用的实现。目标解决当前类不负责被依赖类实例的创建和初始化。
Part2: What is Dependency
依赖是程序中常见的现象,假设有 A和B都被C耦合依赖着,在 OOP 编程中依赖无处不在。依赖形式有多种表现形式,比如一个类向另一个类发消息,一个类是另一个类的成员,一个类是另一个类的参数。
Part3: When is use Dependency injection
eg: 以用户调用 API 层打印日志来说明
- LoggerService被ApiService和UserService所依赖
- ApiService被UserService所依赖
1、存在的问题
- Unit tests 很难写
- 组件不易复用和维护,可扩展性比较低
- UserService 不应该承载ApiService和LoggerService实例的创建。
2、如何解决
采用依赖注入,UserService不负责被依赖类的创建和销毁,而是通过外部传入api和logger对象的方式注入。常见依赖注入方式有三种,本文主要以构造器注入为例解释。
Part4: Implement simply Dependency injection
1、预备知识
- ES6 的平时业务中相对使用较少的特性:Reflect、Proxy、Decorator、Map、Symbol
- 了解 Dependency injection,ES/TS 装饰器
- 深入理解 TypeScript - Reflect Metadata
1)Reflect
简介
Proxy 与 Reflect 是 ES6 为了操作对象引入的 API,Reflect 的 API 和 Proxy 的 API 一一对应,并且可以函数式的实现一些对象操作。
另外,使用 reflect-metadata 可以让 Reflect 支持元编程
类型获取
- 类型元数据:design:type
- 参数类型元数据:design:paramtypes
- 函数返回值类型元数据:design:returntype
2)Decorators
3)Implement simply Dependency injection
只实现了依赖提取的核心部分,依赖注入还有一个部分是Container容器存储相关。
Resolve Dependency
4)Implement simply Dependency injection with container
Part5: APIs of InversifyJS with TypeScript
1、使用步骤
- Step 1: 声明接口及类型
- Step 2: 声明依赖使用@injectable & @inject decorators
- Step 3: 创建并配置一个 Container
- Step 4: 解析并提取依赖
2、示例
声明接口及类型:
声明依赖:
也可以使用 property injection 代替 constructor injection ,这样就不用声明构造函数。
创建并配置一个 Container
解析依赖
Classes as identifiers and circular dependencies
An exception:
Part6: FrameWorks
依赖注入一般都借助第三方框架来实现,实现需要考虑循环依赖,错误处理,容器存储等。
- tsyringe:https://github.com/microsoft/tsyringe
- 实践:https://github.com/DTStack/molecule
- InversifyJS:https://github.com/inversify/InversifyJS
- 实践: https://codesandbox.io/s/github/inversify/inversify-express-example/tree/master/?file=/BindingDecorators/controller/user.ts
数栈是云原生—站式数据中台PaaS,我们在github和gitee上有一个有趣的开源项目:FlinkX,FlinkX是一个基于Flink的批流统一的数据同步工具,既可以采集静态的数据,也可以采集实时变化的数据,是全域、异构、批流一体的数据同步引擎。大家喜欢的话请给我们点个star!star!star!
github开源项目:https://github.com/DTStack/flinkx
gitee开源项目:https://gitee.com/dtstack_dev_0/flinkx