内容简介:InversityJS 是一个 IoC 框架。IoC(Inversion of Control) 包括依赖注入(Dependency Injection) 和依赖查询(Dependency Lookup)。相比于类继承的方式,控制反转解耦了父类和子类的联系。
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()) // 流行音乐古典音乐
上述案例可以抽象为下图:
虚线表示可以注入,但在代码中没有表现出来。
代码流程可概括如下:
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 } } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 解读Bento Android框架的开源细节
- 匠心独运解读Mybatis源码,纯手工打造开源框架
- 解读 2018:13 家开源框架谁能统一流计算?
- 从算法到工程,解读阿里巴巴大规模图表征学习框架Euler
- 如何确保多步操作的事务性?HBase基础框架级特性Procedure解读
- Phoenix解读 | Phoenix源码解读之索引
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法导论
[美] Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest、Clifford Stein / 高等教育出版社 / 2002-5 / 68.00元
《算法导论》自第一版出版以来,已经成为世界范围内广泛使用的大学教材和专业人员的标准参考手册。 这本书全面论述了算法的内容,从一定深度上涵盖了算法的诸多方面,同时其讲授和分析方法又兼顾了各个层次读者的接受能力。各章内容自成体系,可作为独立单元学习。所有算法都用英文和伪码描述,使具备初步编程经验的人也可读懂。全书讲解通俗易懂,且不失深度和数学上的严谨性。第二版增加了新的章节,如算法作用、概率分析......一起来看看 《算法导论》 这本书的介绍吧!