迈向angularjs2系列(5):依赖注入
一: 为什么要依赖注入
1.构造器引入依赖
假设一个类Car类依赖于Engine(引擎)类、Transition(变速箱)类,可使用构造器来完成。
//类似如下代码
class Engine{}
class Transmission{}
class Car {
engine;
transmisssion;
constructor(){
this.engine=new Engine();
this.transmisssion=new Transmission();
}
构造函数创建似乎简洁明了,但是不灵活。Car类和其他两个类耦合度高,每当创建Car类,也会创建Engine类和Transmission类,它们的可测试性分别受到影响。
2.引入依赖注入
有后续的完善哦,这里只是简单的重构了一下。
class Engine{}
class Transmission{}
@Injectable
//仅仅改动的地方
class Car {
engine;
transmisssion;
constructor(engine:Engine,transmission:Transmisson){
this.engine=engine;
this.transmisssion=transmission;
}
}
二: 配置注射器
在angular2中,使用注射器实现依赖注入机制。
完整的代码injector.ts:
import "reflect-metadata";
//引入 reflect-metadata 库来使用元数据反射 API:
import {
Injector,Inject,Injectable,OpaqueToken,provide,ReflectiveInjector
} from "@angular/core";
const BUFFER_SIZE=new OpaqueToken("buffer-size");
//token常量,在整个应用里唯一、不可重复定义的值。
class Buffer{
//@Inject装饰器接收依赖对象的token
constructor(@Inject(BUFFER_SIZE) private size:Number){
console.log(this.size);
}
//Buffer类接收依赖参数size
}
//使用生成的元数据解析依赖关系
@Injectable()
class Socket {
constructor(private buffer:Buffer){}
} const injector: Injector =
ReflectiveInjector.resolveAndCreate([
{provide: BUFFER_SIZE, useValue: '42'},
Buffer,
Socket
]);
//初始化注射器
injector.get(Socket);
1.导入
import "reflect-metadata";
import {
Injector,Inject,Injectable,OpaqueToken,provide,ReflectiveInjector
} from "@angular/core";
2.token的定义和Inject装饰器接收token
const BUFFER_SIZE=new OpaqueToken("buffer-size");
BUFFER_SIZE这个常量,可以看做整个应用中唯一、不可重复定义的值。
3.使用生成的元数据解析依赖关系
@Injectable()
class Socket {
constructor(private buffer:Buffer){}
}
Socket类用@Injectable()进行装饰,强制typescript编译器生成额外的元数据,用以描述指定的类能够注入哪些类型的依赖。这有点像angular1代码的压缩,一定要写成数组形式,以便压缩后的代码能够知道注入的是什么参数。
所以,如果省略掉装饰器,angular2的DI机制就不知道哪些符号对应的依赖关系需要进行注入了。
class Socket {
constructor(@Inject(Buffer)private buffer:Buffer){}
}
//与上面代码等价哦
4.初始化注射器
const injector: Injector =
ReflectiveInjector.resolveAndCreate([
{provide: BUFFER_SIZE, useValue: '42'},
Buffer,
Socket
]);
//使用resolveAndCreate静态方法创建Injector类的实例
resolveAndCreate是一个工厂方法,可接收一个provider数组作为参数,返回值是一个新的Injector实例。
resolvede的意思是provider将会执行一次解析过程。
5.前向引用
如果Socket类定义在Buffer类之前呢,由于Js代码的从上往下执行,会报错说Buffer没有定义undefined。
那么除了用正确的顺序来定义它们之外,还有一种解决方案,前向引用。
import {forwardRef} from"@angular/core"
@Injectable()
class Socket {
constructor(@Inject(forwardRef(()=>Buffer)) private buffer:Buffer){}
}
//前向引用唯一要做的就是使用@Inject装饰器,并把forwardRef函数的执行结果传给它。
forwardRef是一个高阶函数,只接收一个函数,并负责返回需要被注入的依赖。这可以算是延迟依赖类型解析的方案。而之前的模式时第一次实例化依赖符号就会被解析,默认情况下,声明类的时候就需要解析符号。
迈向angularjs2系列(5):依赖注入的更多相关文章
- 拥抱.NET Core系列:依赖注入(2)
上一篇"拥抱.NET Core系列:依赖注入(1)"大体介绍了服务注册.获取和生命周期,这一篇来做一些补充. 由于内容跨度大(.NET Core.ASP.NET Core),所以文 ...
- .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]
原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...
- .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]
原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...
- .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...
- .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]
原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...
- .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式
原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...
- .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式
原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...
- .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC
原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...
- 迈向angularjs2系列(1):typescript指南
typescript指南 前言 typescript是angularjs2推荐使用的脚本语言.它由微软2012年首次发布. 一. typescript和javascript的区别 1.从遵循的规 ...
随机推荐
- serv-u中如何映射网络驱动器
用一台机器作服务器,但硬盘空间不足,想通过影射网络驱动器来实现ftp的空间扩容! 如何映射网络硬盘或文件? 首先打开我的电脑--工具选项--映射网络驱动器: 如图示: 在文件夹输入映射路径:\\XXX ...
- Windows 10 IoT Serials 9 – 如何利用IoTCoreAudioControlTool改变设备的音频设备
大家知道,在Windows 10 IoT Core上,如果用户外接了USB声卡.带有麦克风的摄像头之类的硬件,就会有多个音频设备可以用.但是,系统目前并没有提供直接的UI来设置音频的输入或者输出设备. ...
- 【RequireJS】requireJS的基础知识
1. requirejs的优点 1)异步加载依赖的文件 2)管理文件加载顺序 3)管理文件加载的包路径 2. requirejs下载地点 https://github.com/jrburke/requ ...
- 微信小程序框架探究和解析
何为框架 你对微信小程序的技术框架了解多少? 对wepy 框架进行一系列的深入了解 微信小程序框架解析和探究 小程序组件化框架WePY 在性能调优上做出的探究 开发者培训班上海专场PPT分享:小程序框 ...
- 求m区间内的最小值
洛谷P1440 求m区间内的最小值 ............................................................................... 以上 ...
- java大数取余
java大数取余: 类方法:BigInteger.divideAndRemainder() 返回一个数组,key = 0为商key = 1为余数 import java.util.*; import ...
- java集合框架的讲解
下面要开始java中相关集合框架的学习啦. Are you ready?Let's go~~ 今天要讲解的Java中的集合框架. 1) 首先查看jdk中Collection类的源码后会发现如下内容: ...
- Ubuntu 虚拟机支持与windows机器复制粘贴
实现虚拟机VMware上Ubuntu与主机windows之间互相复制与粘贴 实现VMware中Ubuntu与主机Windows系统之间的相互复制与粘贴(公用粘贴板): 1.在虚拟机VMware的菜单栏 ...
- PAT (Basic Level) Practise (中文) 1017. A除以B (20)
1017. A除以B (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题要求计算A/B,其中A是不超过 ...
- 三菱Q系列PLC基本指令讲解
1.数据传送指令MOV和MOVP,格式为 MOV SRC1 DES1 表示条件接通,将SRC1的值传送到DES1寄存器中,带P的表示只在条件接通的上升沿指令执行一个扫描周期,不带P ...