上一节我们学习了didi
依赖注入框架,如何使用模块,以及如何创建子依赖注入器,今天我们继续深入理解它们,先来看看第一个例子:
const {Injector} = require('didi');
//定义一个父模块
const moduleParent = /** @type ModuleDeclaration */ ({
a: [ 'value', 'a-parent' ]
});
//定义一个子模块
const moduleChild = /** @type ModuleDeclaration */ ({
b: [ 'factory', function(a) {
return {
a: a
};
} ]
});
const injector = new Injector([ moduleParent ]);
const child = injector.createChild([ moduleChild ]);
const aResult = child.get('b');
console.log('bComponent:',aResult);
输出如下:

从以上输出我们可以得出一个结论,如果子加载器在子模块中没有找到响应的组件,会从父模块中寻找响应的组件进行加载。
再来看看另外一种情况:
const {Injector} = require('didi');
const moduleParent = /** @type ModuleDeclaration */ ({
b: [ 'factory', function(c) {
return 'b-parent';
} ]
});
const moduleChild = /** @type ModuleDeclaration */ ({
c: [ 'value', 'c-child' ]
});
const injector = new Injector([ moduleParent ]);
const child = injector.createChild([ moduleChild ]);
const bResult = child.get('b');
输出如下:

此时,子加载器去获取父模块的组件b
,此时组件b
依赖于组件c
,在此情况下,父模块的依赖项不会去子模块寻找,因此抛出了一个错误,没有c
组件的provider。
我们得出一个结论,如果子加载器加载的组件来自于父模块,它的依赖项不会从子模块中去寻找。
下面我们看看另一种情况:
const {Injector} = require('didi');
const moduleParent = /** @type ModuleDeclaration */ ({
b: [ 'factory', function(c) {
return {
c: c
};
} ],
c: [ 'value', 'c-parent' ]
});
const injector = new Injector([ moduleParent ]);
const bResult = injector.get('b');
console.log('first bComponent:',bResult);
const moduleChild = /** @type ModuleDeclaration */ ({
c: [ 'value', 'c-child' ]
});
const child = injector.createChild([ moduleChild ], [ 'b' ]);
const b1Result = child.get('b');
console.log('second bComponent:',b1Result);
输出如下:

从以上输出可以看出,在通过子模块创建子加载器的时候,会强制创建b
组件的依赖项子模块的c
组件,此时,如果是父加载器加载b
组件,则会使用父模块的c
组件作为b
组件的依赖项,而如果用子加载器加载b
组件,那么会使用子模块的c
组件作为b
组件的依赖项。
我们再看看一个关于不同模块的依赖项的例子
const {Injector} = require('didi');
const injector = new Injector([
{
__exports__: [ 'foo' ],
'foo': [
'factory',
function(conflict) {
return conflict;
}
],
'conflict': [ 'value', 'private-from-a' ]
},
{
__exports__: [ 'bar' ],
'bar': [
'factory',
function(conflict) {
return conflict;
}
],
'conflict': [ 'value', 'private-from-b' ]
}
]);
console.log('foo:',injector.get('foo'));
console.log('bar:',injector.get('bar'));
输出如下:

从以上可以看出,不同的模块依赖的组件conflict
是可以不同,而且这些私有的组件即使名字一样也不会有冲突。