Yii1.x常常被批评为强耦合,很难使用第三方库。一般持这样的观点的人会说起Yii1对DI的支持不够,或者说几乎没有。其实我的认为仍是有一些朴素的支持的,好比application就是一个DI,各类组件都是经过 Yii::app()->xxx 的方式建立并引用的,怎么能说没有DI呢?至少实现了一些基本要素:php
做为富有进取心的框架,Yii2确定不能再继续受这样的批评啦,因而在DI上作了不少工做,达到了DI的几个基本要求html
关于Yii2的依赖注入实现与原理,有网友已经给出了详细的分析,推荐你们看看。地址:http://www.digpage.com/di.html,写得至关好啦,很赞。程序员
既然依赖注入听说有利于下降各个模块之间的耦合度,那么就让咱们试试效果。架设咱们的Store模块须要一个AdminContext的依赖,那么咱们能够在模块的init方法中将依赖加进去:web
<!-- lang: php --> //文件 StoreModule.php public function init() { parent::init(); //开始添加依赖 $this->set('ac',[ 'class'=>'mtBridge\services\AdminContext', ]); }
上面的代码,由于Module自己是继承自ServiceLocator,因此能够直接使用set方法添加一个依赖项。再看看AdminContext类的定义:app
<!-- lang: php --> class AdminContext implements IAdminContext { public $env; public $cs; public function __construct(EnvContext $e,CacheService $c) { $this->env = $e; $this->cs = $c; } public function doCallTest() { $siteName = $this->env->getSiteName(); $s = $this->cs->getCacheKey(1,'site'); return array($siteName,$s); } }
发现AdminContext的构造函数须要EnvContext和CacheService两个类型的对象做为参数,正好测试Yii2的DI的依赖的子依赖的支持。加个测试页面吧。框架
<!-- lang: php --> class TestController extends \yii\web\Controller { public function actionIndex() { list($siteName,$key) = $this->module->get('ac')->doCallTest(); list($siteName2,$key2) = $this->module->get('ac')->doCallTest(); echo $siteName . '--key--' . $key; } }
运行这个action的代码,正常输出,而且两次调用,ac也就实例化一次。yii