解读 IoC 框架 InversifyJS

栏目: 后端 · 发布时间: 6年前

内容简介:InversityJS 是一个 IoC 框架。IoC(Inversion of Control) 包括依赖注入(Dependency Injection) 和依赖查询(Dependency Lookup)。相比于类继承的方式,控制反转解耦了父类和子类的联系。

解读 IoC 框架 InversifyJS

InversityJS 是一个 IoC 框架。IoC(Inversion of Control) 包括依赖注入(Dependency Injection) 和依赖查询(Dependency Lookup)。

相比于类继承的方式,控制反转解耦了父类和子类的联系。

案例解析

import 'reflect-metadata'  
import { inject, injectable, Container } from 'inversify'

const container = new Container()

@injectable()
class PopMusic {  
  getName() {
    return '流行音乐'
  }
}
container.bind('request1').to(PopMusic)

@injectable()
class ClassicalMusic {  
  getName() {
    return '古典音乐'
  }
}
container.bind('request2').to(ClassicalMusic)

@injectable()
class Music {  
  pm: any
  cm: any
  constructor(
    @inject('request1') popMusic: any,
    @inject('request2') classicalMusic: any) {
    this.pm = popMusic
    this.cm = classicalMusic
  }

  getName() {
    const result = this.pm.getName() + this.cm.getName()
    return result
  }
}
container.bind('Plan').to(Music)

const music: any = container.get('Plan')  
console.log(music.getName()) // 流行音乐古典音乐

上述案例可以抽象为下图:

解读 IoC 框架 InversifyJS

虚线表示可以注入,但在代码中没有表现出来。

代码流程可概括如下:

1.将所有相关类(这里指 Music、popMusic、classicMusic) 通过 @injectable 声明进 container 容器;

2.通过 container.get() 获取 container.bind().to(target) 中的目标对象(这里指 Music);

3.如果目标对象中的 constructor() 里有 @inject() , 则将相应的实例(这里指 PopMusic 与 classicalMusic 的实例)当作构造函数的参数'注入';

inject/injectable 相关源码

inject 源码简化如下:

// 这是一个属性装饰器
function inject(serviceIdentifier) {  
  return function (target, targetKey) {
    const metadataValue = { [targetKey]: [Metadata { key: 'inject', value: serviceIdentifier })] }
    Reflect.defineMetadata('inversify:tagged_props', metadataValue, target.constructor);
  }
}

injectable 源码简化如下:

// 这是一个类装饰器
function injectable() {  
  return function (target) {
    const metadataValue = []
    Reflect.defineMetadata('inversify:paramtypes', metadataValue, target)
    return target
  }
}

从简化版源码中可以看到 inject/injectable 最终是对 Reflect.defineMetadata() 的一个使用。可以将 metadata 看成是一种相对高效的数据结构。

reflect-metadata

InversityJS 深度结合了 reflect-metadata , reflect-metadata 在 Reflect 基础上对其 api 进行了扩展。

metadata 本质上是一个 WeakMap 对象。扩展: Map 和 WeakMap 的区别

Reflect.defineMetadata(metadataKey, metadataValue, target[, propertyKey]) 简化版实现如下:

const Metadata = new WeakMap()

function defineMetadata(metadataKey, metadataValue, target, propertyKey) {  
  metadataMap = new Map()
  metadataMap.set(metadataKey, metadataValue)
  targetMetadata = new Map()
  targetMetadata.set(propertyKey, metadataMap)
  Metadata.set(target, targetMetadata)
}

Reflect.getOwnMetadata(metadataKey, target[, propertyKey]) 简化版实现如下:

function getOwnMetadata(metadataKey, target, propertyKey) {  
  var targetMetadata = Metadata.get(target)
  var metadataMap = targetMetadata.get(propertyKey)
  return metadataMap.get(metadataKey)
}

其数据结构可表示如下:

WeakMap {  
  target: Map {
    propertyKey: Map {
      metadataKey: metadataValue
    }
  }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web性能优化

Web性能优化

Patrick Killelea 谢 / 谢文亮 / 清华大学出版社 / 2003-11-01 / 49.00元

本书讲述如何将Web性能调至最佳状态。书中不仅谈到了Web服务器软件的优化,而且还涉及到如何流水化处理Web内容,如何从浏览器端着手优化性能,如何调校客户端和服务器的硬件,以及如何最大限度地使用网络本身的特性。 书中的内容涉及到影响性能好坏的本质,并为得到立竿见影的效果提供了具体建议。本书向您娓娓道出评价计算性能高低的准则,并在后半部分讲述从客户端、网络直到服务器这一链条中每个环节的薄弱之一起来看看 《Web性能优化》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器