本库 API 和 inversify API 的对比
注意:本库使用 TC39 Stage 3 装饰器规范,不需要
reflect-metadata。
inversify 需要依赖reflect-metadata实现构造函数参数的自动类型推导,同时还需要配置emitDecoratorMetadata: true。
Container
本库和 inversify 都使用 Container。 历史版本中本库参考 Angular 使用 Injector 作为服务的容器,新版本改为 Container。
本库只实现了 inversify 中 Container 的部分方法。已经实现的方法绝大多数应该是和 inversify 等效的。确定的只有 onActivation 和 onDeactivation 的接口定义发生了变化。
Token
对应 inversify 的 ServiceIdentifier。
inversify 中没有对 ServiceIdentifier 类型做太多限制,基本上任何 js 变量都可以作为 ServiceIdentifier,常见的有字符串和 Symbol,以及 class 类。
本库使用 Token 实例代替 inversify 中的字符串和 Symbol对象。
本库也支持直接把 class 类作为 ServiceIdentifier。
实际上本库只支持 Token 实例和 class 类作为 ServiceIdentifier,是因为这样可以方便 ide 自动推导类型。
LazyToken
inversify 的 LazyServiceIdentifier
@Inject
inversify 的 inject
- 本库当前版本(Stage 3 装饰器)只支持属性注入(Field Decorator),不支持构造函数参数注入(Parameter Decorator)。
- inversify 同时支持属性注入和构造函数参数注入。
@Optional
inversify 的 optional
@Self
inversify 没有提供 @Self 装饰器
本库是借鉴的 Angular 中的@Self 这个 API
@SkipSelf
inversify 没有提供 @SkipSelf 装饰器
本库是借鉴的 Angular 中的@SkipSelf 这个 API
@PostConstruct
inversify 的 postConstruct
激活顺序差异:
- 本库:
binding handler → container handlers → @PostConstruct - inversify:
@PostConstruct → binding handler → container handlers
继承行为: 本库与 inversify 相同,沿继承链向上查找,执行第一个找到的 @PostConstruct 方法。
@PostConstruct 装饰器所修饰的方法可以返回Promise,代表服务是异步初始化的。其他服务如果依赖这个异步服务,那么可以继续使用@PostConstruct来等待前置依赖的服务完成之后再开始初始化自己的服务。
@PreDestroy
inversify 的 preDestroy
本库与inversify激活顺序相同:
- container handlers --> binding handler --> preDestroy
装饰器采用首字母大写风格
其实严格来说,装饰器也只是一个普通的函数,首字母应该小写。
但是这里借鉴了 Angular 中的命名风格,采用首字母大写。
主要还是个人偏好。
decorate
inversify 的 decorate
主要用于在 javascript 项目中手动使用装饰器函数。
@LazyInject 和 createLazyInject
inversify 本身没有提供相应的方法,但是第三方库 提供了类似的方法。实际上本库也是参考的这个开源库的实现。
该三方库只提供了getDecorators方法,类似本库的createLazyInject方法。
相关细节参考这里
Binding
- 本库的
Binding类是公开导出的,可以直接用于类型标注。 - inversify 的
Binding类不是公开导出的,无法直接引用。