TypeScript 来做依赖注入的限制

时间: 2019-08-13阅读: 119标签: 代码

依赖注入 是编写可测试/复用代码的关键。 在 TypeScript 中所有对象、属性和方法都有类型,可以大幅简化人工标注的代码,这让很多人重新考虑在 JavaScript 中实现依赖注入。 比如 Angular2 以后的 DI 实现 。 本文用来讨论 TypeScript 仍然无法解决哪些问题,以及相关技术可能存在的风险。

首先简单过一下基于 TypeScript 做依赖注入的步骤。 ES6 中提出了 Reflect 用来访问和操作对象对象属性。 而 Reflect Metadata 提案 让 Reflect API 可以提供对类型的元数据进行操作的方法。 这样就可以在 tsc 编译时产出注册元数据的代码,在运行时就可以读到编译时的类型了,这一类型就提供了依赖注入的 Token。 运行时的注入器根据函数签名的类型拿到依赖关系,再根据类型对应的 Provider 来创建依赖树。


装饰器可能和标准分裂

TypeScript 编译 Reflect Metadata 需要打开一个叫做 emitDecoratorMetadata 的开关, 但这个开关只有在存在装饰器的方法上起作用。 不知这是设计缺陷还是故意的,总之要通过加装饰器来生成 metadata,两个特性是绑在一起的。 也就是说基于 TypeScript 做依赖注入一定要用 decorator。 坏消息是 ECMA 最新的 Proposal Decorators 和 TypeScript 提出的装饰器很不一样。 如果大量使用相关特性,后续可能面临代码迁移。


函数无法装饰

目前 TypeScript 的编译器中,装饰器不能修饰函数(对象之外的独立 function)。 装饰器无法装饰独立的方法,也就是说无法为独立的工厂方法自动生成依赖列表。 只能把工厂方法改成工厂类,否则就需要手动声明依赖。

A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. –typescriptlang.org

这就是为什么 Angular 中只有 factory 需要手动声明依赖列表 :

export let heroServiceProvider =
  { provide: HeroService,
    useFactory: heroServiceFactory,
    deps: [Logger, UserService]
  };

NestJS 也只有 factory 类型的 provider 需要提供 inject 数组:

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};


interface 仍然需要显式声明

这一小节标题比较抽象,需要先看个例子。 这是一个依赖注入的典型场景(省略了一些注册、装饰器等操作):

// 声明一个 Person 类
class Person {
  constructor(p: Parent, a: Age) {}
}

// 请求创建一个 Person 对象
const person = injector.create(Person)

依赖注入的核心设计就是使用和创建分离。 这里我们要用一个 Person 对象,如何创建完全交给 injector,它会去分析并创建 Person 的依赖( [Parent, Age] ),然后再创建 Person 并返回。 如果 Parent 和 Age 不是具体的类而是接口,那么运行时拿到的依赖列表将会是 [Object, Object] ,这样 injector 就无法知晓和创建依赖了。 所以对于接口类型,仍然需要声明一下给运行时一些信息,比如这样:

class Person {
  constructor(@inject('IParnet') p: IParent, @inject('IAge') a: Age) {}
}

其实类似这样的声明有个通用的名字叫做 Inject Token,本是用于基本数据类型注入,或希望通过类型之外的信息来创建的时候。 只是在 TypeScript 中,即使是非常常用的接口也必须采用这种相对复杂的写法。

原文:https://harttle.land/2019/08/12/typescript-limit-for-dependency-injection.html


链接: http://www.fly63.com/article/detial/4666

程序员吐槽:经常熬夜敲代码,谈了四年的女朋友提出分手了

这年头说起程序员,普通人都会很羡慕他们的高薪,毕竟刚工作就可以月薪上万,三五年工作月薪两万,干一年相当于普通人干个5年的,谁又能不眼红呢?不过程序虽然高薪,但也有自己的苦处。

如何写出优雅耐看的JavaScript代码?

在我们平时的工作开发中,大多数都是大人协同开发的公共项目;在我们平时开发中代码codeing的时候我们考虑代码的可读性、复用性和扩展性。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。

代码审查问题手册

代码审查列表,是代码审查的明确规则和指导手册,它可以使代码审查为你的团队带来更多好处,并且能够显著提升代码审查的速度。研究表明,使用代码审查列表的审阅者的表现要优于不使用的审阅者

开发人员花在实际编写代码上的时间有多少?

2019年6月,Tidelift和The New Stack联合对专业软件开发人员进行了调查。约400人接受了调查,表明如今他们如何使用开源软件、什么因素在阻碍他们以及什么工具和策略可以帮助他们更高效地使用开源软件。尤其是,就这次调查而言

优秀的程序员要学会少敲代码,多思考!

如果只把一个字符一个字符地敲代码叫做 Coding,未免悲哀了一点。优秀的项目,编码阶段实际敲代码的时间不会很长;优秀的程序员,大部分时间都用来思考了。这个时候,你就需要学会代码评审,什么?

程序员面试中徒手写代码的意义?

其实我在本科的时候,就有一次有机会面试谷歌的实习生。但是因为在徒手写代码的时候,失败了,成了我毕生的遗憾。也造成了我在这类面试中的恐惧心理。当时,我只是一名大三学生,我 C 语言课程成绩优秀,算法课成绩一般

后端传过来一个JS代码,前端拿到之后执行

今天收到了一个需求,居然是后端给我传过来一个JS代码,然后前端去执行。因为后端传过来的JS代码是一个字符串,所以刚开始有点懵,以前也没有做过这样的东西所以刚开始没有方法。

Js代码中的span拼接

今天遇到一个小需求,用bootstrap的table只有两个字段,占用太宽,页面不美观,组长要求用拼接,一行几列的形式展现出来。我在form表单中拼接了span,遇到以下问题:

怎么样才能不写出别人嘴里的烂代码?

每个人对于好的代码在自己不同的时期都有不一样的理解。当个人所在的层次变化,好代码的概念也会跟着变化。老夫上手就是复制粘贴,别跟我说什么编码规范,设计模式。

你不知道的 useCallback

对于新手来说,没写过几次死循环的代码都不好意思说自己用过 React Hooks。本文将以useCallback为切入点,谈谈几个 hook 的使用场景,以及性能优化的一些思考。

fly63.com版权所有,内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权,请与小编联系!情况属实本人将予以删除!

广告赞助文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全