依赖注入
注入的核心作用是解耦。
#我们以React 0.13版本为例来看一下React的注入机制。
入口:ReactDOM类
var ReactCurrentOwner = require('./ReactCurrentOwner');
var ReactDOMTextComponent = require('./ReactDOMTextComponent');
var ReactDefaultInjection = require('./ReactDefaultInjection');
var ReactInstanceHandles = require('./ReactInstanceHandles');
var ReactMount = require('./ReactMount');
var ReactPerf = require('./ReactPerf');
var ReactReconciler = require('./ReactReconciler');
var ReactUpdates = require('./ReactUpdates');
var ReactVersion = require('./ReactVersion');
var findDOMNode = require('./findDOMNode');
var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer');
var warning = require('fbjs/lib/warning');
ReactDefaultInjection.inject() -----------------(1)
ReactDOM类的(1)是核心。这一行代码主要做的事情就是调用了
ReactDefaultInjection 类的 Inject 方法。
这里我们就要转到ReactDefaultInjection类去了。先来看看ReactDefaultInjection类都有些什么。
ReactDefaultInjection类
首先,源码内容过多,这里就不全部贴出来,而是选择了其中的一项作为例子来说明。
var ReactInjection = require('./ReactInjection');
'引入了ReactInjection类,这个类是一个辅助类,
他的作用是导出一个React中所有需要注入依赖的类所提供的注入接口。
比如EventPluginHub这个类就需要一个依赖,名字叫做DefaultEventPluginOrder。
而EventPluginHub这个类提供了一个对外的接口injectEventPluginOrder,
用来注入自己需要的依赖(将自己需要的依赖DefaultEventPluginOrder当做参数传
递进来。这也是注入的实质。)。'
var DefaultEventPluginOrder = require('./DefaultEventPluginOrder');
'引入了DefaultEventPluginOrder类'
function inject() {
ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); -------------------(2)
}
ReactDefaultInjection类主要的就是引入各个类需要的依赖,而后调用各个类暴漏出来的注入方法(全都是inject开头的方法),来将需要的依赖注入到类中。
我们来看一下ReactInjection类中的内容
ReactInjection类
var DOMProperty = require('./DOMProperty');
var EventPluginHub = require('./EventPluginHub');
var ReactComponentEnvironment = require('./ReactComponentEnvironment');
var ReactClass = require('./ReactClass');
var ReactEmptyComponent = require('./ReactEmptyComponent');
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
var ReactNativeComponent = require('./ReactNativeComponent');
var ReactPerf = require('./ReactPerf');
var ReactRootIndex = require('./ReactRootIndex');
var ReactUpdates = require('./ReactUpdates');
var ReactInjection = {
Component: ReactComponentEnvironment.injection,
Class: ReactClass.injection,
DOMProperty: DOMProperty.injection,
EmptyComponent: ReactEmptyComponent.injection,
EventPluginHub: EventPluginHub.injection,-------------------(3)
EventEmitter: ReactBrowserEventEmitter.injection,
NativeComponent: ReactNativeComponent.injection,
Perf: ReactPerf.injection,
RootIndex: ReactRootIndex.injection,
Updates: ReactUpdates.injection
};
module.exports = ReactInjection;
如上所示。ReactInjection类主要就是统一了一下都有那些地方需要注入内容。比如(3)就是我们上边例子说的EventPluginHub这个类就需要注入一些依赖。
接下来我们来看一下,需要依赖的类,比如EventPluginHub内部结构。
EventPluginHub类
var EventPluginHub = {
'
1 为了看起来清楚,我将多余的代码删除。
2 多余的代码主要也是为了注入其他的内容
3 该类提供了一个injection属性,injection属性是一个对象,期内包含
了很多的注入方法。
4 他被代码(3)引入了ReactInjection类中
5 而后被代码(2)执行了,而后传递进来了DefaultEventPluginOrder类
6 此处的injectEventPluginOrder方法,是在EventPluginRegistry类中写着。
7 如此一来,EventPluginHub类需要用到的依赖DefaultEventPluginOrder
类就被注入进来了。
'
/**
* Methods for injecting dependencies.
* 注入依赖的方法
*/
injection: {
injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
},
最后我们看看注入进来的类DefaultEventPluginOrder,他是什么。
DefaultEventPluginOrder类
'
说一下keyOf的作用,就是拿取出给定的对象内的每一项ke-value的key值。
在取出key值之前要判断一下这key是否是给定的对象的自有属性。
'
var DefaultEventPluginOrder = [
keyOf({ ResponderEventPlugin: null }),
keyOf({ SimpleEventPlugin: null }),
keyOf({ TapEventPlugin: null }),
keyOf({ EnterLeaveEventPlugin: null }),
keyOf({ ChangeEventPlugin: null }),
keyOf({ SelectEventPlugin: null }),
keyOf({ BeforeInputEventPlugin: null })
];
'
最后说一下这个模块的作用:
返回一个数组,这个数组内的每一项都是React的事件系统需要用到的事件插件
他们必须要有一个顺序去载入,所以,在这里定义了一下。
'
module.exports = DefaultEventPluginOrder;