迈向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.从遵循的规 ...
随机推荐
- NOIP模拟:能源(二分答案)
题目描述 小美为了拯救世界能源危机,她准备了 n 台蓄电池.一开始每台蓄电池有 ai 个单位的能量. 现在她想把 n 台蓄电池调整到能量相同.对于每台蓄电池可以给另一台蓄电池传递能量.但是会有能量损耗 ...
- CC攻击网站和游戏如何针对性预防?
1:CC攻击原理 CC = Challenge Collapsar,其前身名为Fatboy攻击,是利用不断对网站发送连接请求致 使形成拒绝服务的目的, CC攻击是DDOS(分布式拒绝服务)的一种,相比 ...
- VSCode自定义配色方案
说明 本文更新于2017-07-24,使用VSCode 1.14.1,操作系统为Windows. 配置文件 "文件-首选项-颜色主题"即可显示所有可用的颜色主题,上下选择后Ente ...
- 关于Class.forName(className).newInstance()介绍
Class.forName(xxx.xx.xx) 返回的是一个类 首先你要明白在java里面任何class都要装载在虚拟机上才能运行.这句话就是装载类用的(和new 不一样,要分清楚). 至于什么时候 ...
- 简单设置android启动画面
1.新建Activity,以及layout文件夹里的xml文件2.将新建Activity在AndroidManifest中设为默认Activity,并且添加:android:theme="@ ...
- JavaWeb学习归档(一) - HTTP协议总结
版权声明:本文为博主原创文章,未经博主允许不得转载. 本文转载自我的个人博客:http://www.codingme.net/post/java-web-01 HTTP协议简介 超文本传输协议(HTT ...
- 阿里消息队列中间件 RocketMQ源码解析:Message发送&接收
- seajs的模块化开发--实践笔记
2017-04-02 SeaJS是一个遵循CMD规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制.有效的解决复杂项目中命名冲突.依赖.性能等问题. SeaJS ...
- Spring中使用Map、Set、List、数组、属性集合的注入方法配置文件
(1)下边的一个Java类包含了所有Map.Set.List.数组.属性集合等这些容器,主要用于演示spring的注入配置: package com.lc.collection; import jav ...
- docker安装方法(常见安装出错问题汇总)
参考资料: 1. 开源中国 http://www.oschina.net/translate/nstalling-dockerio-on-centos-64-64-bit?cmp Docker 是一 ...