胖蔡说技术
随便扯扯

聊一聊bpmn-js中的依赖注入框架didi

最近在用bpmn-js来进行flowable流程图的开发工作,不可避免地希望对其运行机制做一个大致的了解,在使用bpmn-js的过程中,bpmn-js基于diagram-js实现的插件式开发方式引起了我的兴趣。于是通过查阅源码希望对齐进一步了解发现:diagram-js是基于一个叫didi的实现的依赖注入功能并贯穿全局,深度使用。接下来我们一起来了解下didi是如何实现依赖注入的。每一个贡献都值得尊敬,顺手给didi开源库一个Star

如何使用?

首先通过didigithub上的文档介绍来了解下如何去使用didi来实现依赖注入。我这里基于文档做了一些结构上的调整,介绍如何创建一个didi的注入组件。依赖注入无非就三个过程:模块实现模块声明模块注入,由于didi组件有其特殊格式要求,我们倒着来介绍。

1、模块注入

didi提供一个Injector对象来对所有注入对象进行初始化:

import { Injector } from 'didi';
const modules = []; // 所有需要注入对象的集合
const injector = new Injector(modules );
// 初始化所有对象
injector.init();

2、模块声明

通过Injector初始化注入的对象需要满足特定的格式:

// ModuleDefinition 导入插件格式
{
  __exports__: [],
  __modules__: [ 'engine', 'license' ]; // 这里的对象最可作为初始化组件的时候传入的参数
  __init__: ['hifiComponent'],// 当前定义的模块名
  __depends__:[    
    AlignElementsModule,
    ContextPadModule,
    PopupMenuModule
  ],
  hifiComponent: [ 'type', HifiComponent ]
}
  • __modules__:这里的对象最可作为初始化组件的时候传入的参数,这里的用法和定义$inject的模块方式等同。
// 源码处理详细请看:didi/lib/annotation.js
export function annotate(...args) {

  if (args.length === 1 && isArray(args[0])) {
    args = args[0];
  }
  args = [ ...args ];
  const fn = args.pop();
  fn.$inject = args;
  return fn;
}
  • __depends__:注入当前定义模块内部的依赖, 在加载当前模块之前会预先加载这些依赖模块。
  • __exports__:导入内部依赖模块
  • __init__:这里定义当前导入的模块名,数组格式可定义多个,定义后需要添加对应的组件的初始化方式。
  • hifiComponent: [ 'type', HifiComponent ]:通过__init__定义后的模块指定配置对应的初始化方法

3、模块实现

模块的注入实现如下,通过$inject或者__modules__配置的参数可作为模块的参数传入

function Car(e, license) {
  // will inject components bound to 'engine' and 'license'
}

Car.$inject = [ 'engine', 'license' ]; // 这里和__modules__用法一致,

4、重写

模块的注册注入需要保证__init__定义的模块名的唯一性,若模块名相同则会导致后注册的模块功能被覆盖。这可以作为功能自定义覆盖的一种手段来使用。

使用细节

1、模块注册声明方式

上述,我们通过__init__声明模块名后需要提供模块注册方式:

const carModule = {

  // asked for 'car', the injector will call new Car(...) to produce it
  'car': ['type', Car],

  // asked for 'engine', the injector will call createPetrolEngine(...) to produce it
  'engine': ['factory', createPetrolEngine],

  // asked for 'power', the injector will give it number 1184
  'power': ['value', 1184] // probably Bugatti Veyron
};

如上示例,模块注册提供集中方式注册:

  • factory:通过factory方式注入则是直接调用函数进行注入,如上述:creatPetrolEngine(...)
  • value:这种方式直接给模块指定赋值
  • type:指定type方式会默认调用构造函数来注册,如上述:new Car(...)
赞(0) 打赏
转载请附上原文出处链接:胖蔡说技术 » 聊一聊bpmn-js中的依赖注入框架didi
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏