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

如何使用?
首先通过didi
在github
上的文档介绍来了解下如何去使用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(...)
原文始发于微信公众号(胖蔡话前端):推荐前端一个轻量级别的依赖注入库:didi
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/222925.html