时间:2021-05-26
一、前言
依赖注入(Dependency Injection)这个概念的兴起已经有很长时间了,把这个概念融入到框架中达到出神入化境地的,非Spring莫属。然而在前端领域,似乎很少会提到这个概念,难道前端的代码就不需要解耦吗?前端的代码就没有依赖了?本文将以 React 的源码为例子,看看它是如何使用依赖注入这一设计模式的。
二、依赖注入的基本概念
在看代码之前,有必要先简单介绍一下依赖注入的基本概念。依赖注入和控制反转(Inversion of Control),这两个词经常一起出现。一句话表述他们之间的关系:依赖注入是控制反转的一种实现方式。另一种方式叫依赖查找(Dependency Lookup)。
在控制不反转的情况下,某个类如果依赖另一个类,它会自己来创建依赖:
class Person { eat() { const dinner = new Dinner('法国菜'); console.log('开饭啦!,今晚自己做:', dinner.name); }}class Dinner { constructor(name) { this.name = name; }}假设一个人要吃饭,如果控制不反转,就需要自己来做,像上面的代码一样要自己new Dinner。
如果使用控制反转,吃什么就不用自己费脑子了,别人给我做好放到我面前,我直接吃就好!
class Person { eat(dinner) { console.log('开饭啦!,今晚有大厨给我做:', dinner.name); }}也就是说,不需要自己来创建依赖的对象了,由外部传入,这就是依赖注入!
三、React 中的依赖注入
众所周知,React 除了可以在浏览器运行外(ReactDOM),也可以制作 App 在手机端运行(ReactNative)。而两者有大量的代码都是可以共享的,这就是依赖注入的使用场景了。
我们来看下具体是如何注入的:
// ReactDOM.jsvar ReactDefaultInjection = require('ReactDefaultInjection');ReactDefaultInjection.inject();// ReactNative.jsvar ReactNativeDefaultInjection = require('ReactNativeDefaultInjection');ReactNativeDefaultInjection.inject();注入的位置都在框架代码最开始加载的位置。下面以 ReactDOM 为例子,详细讲解注入的逻辑。
先来看看需要注入的对象都有哪些,定义在 ReactInjection.js 这个文件当中:
var DOMProperty = require('DOMProperty');var EventPluginHub = require('EventPluginHub');var EventPluginUtils = require('EventPluginUtils');var ReactComponentEnvironment = require('ReactComponentEnvironment');var ReactEmptyComponent = require('ReactEmptyComponent');var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');var ReactHostComponent = require('ReactHostComponent');var ReactUpdates = require('ReactUpdates');var ReactInjection = { Component: ReactComponentEnvironment.injection, DOMProperty: DOMProperty.injection, EmptyComponent: ReactEmptyComponent.injection, EventPluginHub: EventPluginHub.injection, EventPluginUtils: EventPluginUtils.injection, EventEmitter: ReactBrowserEventEmitter.injection, HostComponent: ReactHostComponent.injection, Updates: ReactUpdates.injection,};module.exports = ReactInjection;这里面每一个 injection 都是一个对象,对象内定义了一个或多个 inject 的方法来注入对应的内容。以ReactUpdates.injection为例子:
// ReactUpdates.jsvar ReactUpdatesInjection = { injectReconcileTransaction: function (ReconcileTransaction) { ... ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; }, injectBatchingStrategy: function (_batchingStrategy) { ... batchingStrategy = _batchingStrategy; },};var ReactUpdates = { ... injection: ReactUpdatesInjection,};可以看到 ReactUpdates 依赖的ReactReconcileTransaction和batchingStrategy就是通过这 2 个方法注入进去的。
有了上面的内容,相当于定义好需要依赖的内容了。下一步就是创建具体的依赖内容,然后注入到需要的地方:
// ReactDefaultInjection.jsvar ReactInjection = require('ReactInjection');var ReactReconcileTransaction = require('ReactReconcileTransaction');var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');...function inject() { ... ReactInjection.Updates.injectReconcileTransaction( ReactReconcileTransaction ); ReactInjection.Updates.injectBatchingStrategy( ReactDefaultBatchingStrategy );}这里的 ReactInjection.Updates 等于 ReactUpdates.injection 这个对象。而 inject 方法,就是在前文的 ReactDOM.js 中调用的方法ReactDefaultInjection.inject()。
上述各个文件整体的调用关系如下:
四、总结
本文介绍了依赖注入的基本概念,并结合 React 的源码讲解具体的使用场景。这样做的主要目的是解耦,可以根据实际的上下文传入不同的依赖对象,优雅的实现了代码的抽象与复用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
一、spring依赖注入使用方式@Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注
Spring依赖注入(DI)的三种方式,分别为:1.接口注入2.Setter方法注入3.构造方法注入下面介绍一下这三种依赖注入在Spring中是怎么样实现的。首
Spring的依赖注入Spring主要支持两种依赖注入方式,分别是属性注入和构造函数注入。同时也支持工厂方法注入方式。属性注入属性注入的方式非常简单,即指通过s
1、ASP.NETCore中的依赖注入此示例展示了框架级依赖注入如何在ASP.NETCore中工作。其简单但功能强大,足以完成大部分的依赖注入工作。框架级依赖注
问题出现原因是由于压缩之后变量变成了,e、s、t等,需要依赖注入的方法没有使用中括号注入,而在function的参数中直接使用,导致压缩之后无法识别需要依赖注入