Angular2 依赖注入之装饰器

下面会从 Angular 的源码分析依赖注入中的的装饰器,基于 angular@4.1.0-beta.1

Angular 依赖注入过程主要有下面几个重要的部分组成:

  • Inject 和 Injectable 装饰器
  • 解析提供商,构造注入器
  • 获取实例化对象

Angular 依赖注入中的一些重要的概念:

Provider :
提供商,下面就是一个Proviver,一共有5种构造提供商的方式:TypeProvider, ValueProvider, ClassProvider, ExistingProvider, FactoryProvider

{ provide: Logger, useClass: Logger }

Token :
令牌,提供商中的第一个参数就是Token,在查找依赖时作为 key 使用。

Injector :
注入器,用于解析依赖和创建对象。

Example

class Engine {
  start() {
    console.log('engine start');
  }
}

class Car {
  engine: Engine;
  constructor(@Inject(Engine) engine) {
    this.engine = engine;
  }
  open() {
    this.engine.start();
    console.log('car open');
  }
}

let inj = ReflectiveInjector.resolveAndCreate([
    Car,
    Engine
]);

let car = inj.get(Car);
car.open();

1. 装饰器

下面主要讲 Inject 和 Injectable 两个装饰器。

1.1 Inject 装饰器

构造器中的@Inject()指明了需要注入的对象类型,这里使用TypeScript的装饰器模式。

Inject装饰器会将 构造器 => [依赖0, 依赖1 …] 这种 Map 数据结构保存在全局变量中,而不是装饰的对象上。而且只是保存了这种数据关系,并不会实际创建对象。,Injector 会从前面保存的数

简单地说就是,Inject 装饰器在 window[‘__core-js_shared__’] 这个对象中保存了一个 Map = { Car() => [ Engine() ] }, 在后面在解析 Provider 的时候,Injector 就是从这里寻找对象的依赖。

当然实际还要复杂的多。

下面将一步步介绍 Inject 注入器做了哪些事,看源码:

在上面的代码编译成 JS 文件时,可以看到如下代码,__param() 函数传入 paramIndex 和 decorator 两个参数,其中 decorator 由 metadata_1.Inject() 得到,这个函数先放到后面。 __decorate 需要四个参数,因为装饰器可以用在函数或属性上面,因此需要对不同的目标作不同的处理。

在本例中只传入了2个参数,分别是 decorators 和 target ( Car ), 因此 r = target. 后面判断是否存在Reflect这个对象,因为这个对象是 es7 中的提案,一般浏览器中不存在,需要使用 polyfills 的方式引入。如果不存在,则对 decorators 中的每一个值执行 d(r),那么 d(r) 这个方法到底做了什么呢?

decorators 中的每一个 decorator 都是 __param() 的处理结果,而它的返回值是一个匿名函数,因此 d(r) 实际执行了这个匿名函数,匿名函数里面又执行了 decorator(). decorator是什么函数呢?

var __decorate = (this && this.__decorate) || func
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值