敲碎时间的人的个人专栏
上一篇

Injector框架理解(九)

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

上一节我们学习了关于didi依赖注入框架的关于组件和加载器作用域相关的使用,今天我们来了解一些初始化的一些使用。

我们还是用一些例子来说明问题

const { Injector } =  require('didi');
const { expect } = require('chai');
const injector = new Injector([
{
  __init__: [ 'foo' ],
  'foo': [ 'factory', function(bar) {
	bar.initialized = true;

	return bar;
  } ],
  'bar': [ 'value', {} ]
}
]);
const bar1 = injector.get('bar');
console.log('bar1:',bar1 );
// when
injector.init();

const bar = injector.get('bar');

// then
expect(bar.initialized).to.be.true;
console.log('init component');

输出如下:

从以上代码可以看出,从加载器中没有获取过foo组件,因此foo不会初始化,但是可以将其配置在__init__中,因此这个组件一开始就直接初始化,然后会将依赖的bar组件设置一个bar.initialized = true,因此我们知道这个值会等于true。

从以上可以得出,在构造Injector的时候,组件是不会初始化的,只有配置在__init__中并且调用init方法的时候,获取调用getinvoke的时候才会初始化相应的组件。

我们继续看下面的一个例子,就是私有组件的初始化情况:

const { Injector } =  require('didi');
const { expect } = require('chai');
const privateBar = {};

const injector = new Injector([
  {
	__exports__: [ 'publicFoo' ],
	__init__: [ function(privateBar) {
	  privateBar.initialized = true;
	} ],
	'publicFoo': [
	  'factory',
	  function(privateBar) {
		return {
		  privateBar
		};
	  }
	],
	'privateBar': [ 'value', {} ]
  }
]);

// when
injector.init();

const publicFoo = injector.get('publicFoo');

expect(publicFoo.privateBar.initialized).to.be.true;
console.log('private module');

输出如下

从以上的代码不难看出,在初始化一个模块的组件的时候,是可以修改私有组件的一些属性的,虽然不能理解为啥要这么设计,不过只要这个init的组件不被暴露出去,应该还是没有多大风险的。从这里不难看出,在初始化的时候,修改了私有组件privateBar的属性,这里有个好处就是,我可以在初始化的时候配置不同的私有实现,起到了扩展代码的作用。

下面我们看看另一个问题,那就是依赖的执行顺序是怎么样的?

const { Injector } =  require('didi');
const { expect } = require('chai');
const loaded = [];

// given
const injector = new Injector([
{
  __depends__: [
	{
	  __depends__: [
		{
		  __init__: [ function() { loaded.push('L2_A'); } ]
		},
		{
		  __init__: [ function() { loaded.push('L2_B'); } ]
		}
	  ],
	  __init__: [ function() { loaded.push('L1'); } ]
	}
  ],
  __init__: [ function() { loaded.push('ROOT'); } ]
}
]);

// when
injector.init();

// then
expect(loaded).to.eql([
  'L2_A',
  'L2_B',
  'L1',
  'ROOT'
]);
console.log('should load in reverse order');

输出如下:

从以上输出可以看出,在初始化组件(模块)的时候,执行的顺序是从内待外的,其实这个也不难理解,只有依赖的组件(模块)构造好了以后才能构造外层的组件。因此我们可以简单的理解为是反序的。

我们再来看看如果多次依赖相同的模块,会发生什么情况?

const { Injector } =  require('didi');
const { expect } = require('chai');
const loaded = [];

  const duplicateModule = /** @type ModuleDeclaration */ ({
	__init__: [ function() { loaded.push('DUP'); } ]
  });

  // given
  const injector = new Injector([
	{
	  __depends__: [
		{
		  __depends__: [
			duplicateModule,
			duplicateModule
		  ],
		  __init__: [ function() { loaded.push('L1'); } ]
		},
		duplicateModule
	  ],
	  __init__: [ function() { loaded.push('ROOT'); } ]
	}
  ]);

  // when
  injector.init();

  // then
  expect(loaded).to.eql([
	'DUP',
	'L1',
	'ROOT'
  ]);
console.log('should de-duplicate');

输出如下

从以上的输出可以看出,这些依赖会重用相同的依赖模块,而不会重复构建模块。

版权声明:著作权归作者所有。