一: 为什么要依赖注入
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.从遵循的规 ...
随机推荐
-
embed标签loop=true背景音乐无法循环
在html网页中加入背景音乐并设置为循环播放.一开始用<embed>标签,设置loop="true", 但是结果发现在IE浏览器可以,但是在chrome浏览器却无法实现 ...
-
ruby on rails爬坑(三):图片上传及显示
一,问题及思路 最近在用rails + react + mysql基本框架写一个cms + client的项目,里面涉及到了图片的上传及显示,下面简单说说思路,至于这个项目的配置部署,应该会在寒假结束 ...
-
每日java基础知识(01)
1.java语言的主要特点. 跨平台性:一个应用可以不经过修改,就直接在不同的平台上运行. 面向对象:java是面向对象的语言,可以使用对象封装事物的属性和行为,可以使用面向对象的思想进行分析设计,并 ...
-
关于解决配置Tomact过程中出现的相关问题
最近在学习JavaWeb, 但是在第一步的时候就出现问题了, 什么问题呢, 就是关于Tomact的配置. 下面我就详细说明一下我配置过程中出现的问题以及怎么解决的, 希望对大家能有所帮助. 首先,我 ...
-
selenium处理弹出窗口
在selenium ui自动化测试过程中,经常会遇到,弹出新窗口,那么会对我们元素定位造成哪些影响呢? 1.元素id或xpath;name都没有问题,就是定位不到. 那如何解决呢?没错webdrive ...
-
Python学习笔记第六周
目录 一.基础概念 面向对象编程 1.面向对象的几个核心特点 1.class类 2.object对象 3.encapsulation封装 4.inheritance继承 5.polymorphism多 ...
-
[转]python ctypes 探究 ---- python 与 c 的交互
近几天使用 python 与 c/c++ 程序交互,网上有推荐swig但效果都不理想,所以琢磨琢磨了 python 的 ctypes 模块.同时,虽然网上有这方面的内容,但是感觉还是没说清楚.这里记录 ...
-
(转阮一峰)深入理解OAuth 2.0
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为R ...
-
传统javabean与spring中的bean的区别
javabean已经没人用了 springbean可以说是javabean的发展, 但已经完全不是一回事儿了 用处不同:传统javabean更多地作为值传递参数,而spring中的bean用处几乎无处 ...
-
常用sql 全记录(添加中)
-- 数据库SQL总结中........... --SQL分类: (CREATE,ALTER,DROP,DECLARE) ---DDL—数据定义语言(SELECT,DELETE,UPDATE,INSE ...