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