一: 为什么要依赖注入

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):依赖注入的更多相关文章

  1. 拥抱.NET Core系列:依赖注入(2)

    上一篇"拥抱.NET Core系列:依赖注入(1)"大体介绍了服务注册.获取和生命周期,这一篇来做一些补充. 由于内容跨度大(.NET Core.ASP.NET Core),所以文 ...

  2. .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]

    原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...

  3. .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]

    原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...

  4. .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]

    为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...

  5. .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]

    原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...

  6. .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...

  7. .NET CORE学习笔记系列(2)——依赖注入【2】基于IoC的设计模式

    原文:https://www.cnblogs.com/artech/p/net-core-di-02.html 正如我们在<控制反转>提到过的,很多人将IoC理解为一种“面向对象的设计模式 ...

  8. .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC

    原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...

  9. 迈向angularjs2系列(1):typescript指南

    typescript指南 前言 typescript是angularjs2推荐使用的脚本语言.它由微软2012年首次发布. 一.    typescript和javascript的区别 1.从遵循的规 ...

随机推荐

  1. 【转载】Android 开发 命名规范

    原文地址:http://www.cnblogs.com/ycxyyzw/p/4103284.html 标识符命名法标识符命名法最要有四种: 1 驼峰(Camel)命名法:又称小驼峰命名法,除首单词外, ...

  2. 【JAVASCRIPT】event对象

    一.preventDefault  与 stopPropagation event.preventDefault() 和 event.stopPropagation() 不是JQuery的方法,是JS ...

  3. 读Zepto源码之Deferred模块

    Deferred 模块也不是必备的模块,但是 ajax 模块中,要用到 promise 风格,必需引入 Deferred 模块.Deferred 也用到了上一篇文章<读Zepto源码之Callb ...

  4. JavaScript的六种继承方式

    继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的 原型链 首先得要明白什么是原型链,在一篇文章看懂proto和prototype ...

  5. Angular4.0从入门到实战打造在线竞拍网站学习笔记之四--数据绑定&管道

    Angular4.0基础知识之组件 Angular4.0基础知识之路由 Angular4.0依赖注入 数据绑定 数据绑定允许你将组件控制器的属性和方法与组件的模板连接起来,大大降低了开发时的编码量. ...

  6. 通过HtppWebRequest发送图片到服务器并保存

    之前写的楼主没有测试,后来发现用起来有点小问题 就修改了一下,现在已经亲测可用 完全没有问题了  下面就开始贴代码了 首先将图片装换成功byte 数组 这个path是图片的路径  例如d:12.png ...

  7. CRM权限管理

    CRM权限管理 一.概念 权限管理就是管理用户对于资源的操作.本 CRM 系统的权限(也称作资源)是基于角色操作权限来实现的,即RBAC(Role-Based Access Control,基于角色的 ...

  8. SMBLoris windows拒绝服务漏洞

    在美国拉斯维加斯举行的2017年度DEF CON黑客大会上,安全研究人员公布了Windows系统上的一个长达20年没有发现的漏洞,该漏洞名为"SMBLoris",黑客可以轻松的使用 ...

  9. python中的类属性和实例属性

    属性就是属于一个对象的数据或者函数,我们可以通过句点(.)来访问属性,同时 Python 还支持在运作中添加和修改属性. 我们先来看看类里面的普通字段: class Test(object): nam ...

  10. private static final long serialVersionUID = 1L;详解

    public class User implements Serializable { /** * serialVersionUID */ private static final long seri ...