yii2 隨筆(七)依賴注入——(4)服務定位器

來源:互聯網
上載者:User
服務定位器定位器是依賴注入的一種解決方式,它包含依賴注入,在解決了依賴注入後,如果服務使用者和服務提供者不是用一個人,那麼使用者要瞭解提供服務的必須參數,這樣才能保證依賴的正確性,這就耦合了使用者和提供者,服務定位器就是解耦這部分的,服務提供者在 ServiceLocator 中註冊服務(同時註冊了依賴),僅僅告訴服務使用者那些服務的名稱或者別名,那麼對於服務提供者和使用者都是好的,使用者只需要知道提供者提供的什麼服務,而不必知道依賴什麼,服務提供者也不必為使用者“胡亂使用”服務而導致的bug所困擾。

那麼yii2是怎麼使用ServiceLocator呢?其實很簡單如下

//魔術方法,public function __get($name){    //得到某個註冊的方法    if ($this->has($name)) {        return $this->get($name);    } else {        return parent::__get($name);    }}//魔術方法查看某個服務是否存在,源碼略public function __isset($name){}//__isset()中調用,查看某個服務是否存在,源碼略public function has($id, $checkInstance = false){}//得到某個服務public function get($id, $throwException = true){    if (isset($this->_components[$id])) {//如果是已經處理的服務,就直接返回        return $this->_components[$id];    }    if (isset($this->_definitions[$id])) {//如定義了該服務        $definition = $this->_definitions[$id];//得到服務的定義        //如果服務是一個閉包,則把閉包註冊到已經執行個體化的服務中,並且返回閉包        if (is_object($definition) && !$definition instanceof Closure) {            return $this->_components[$id] = $definition;        } else {//其他的情況下通過依賴注入產生對象,並且註冊為已處理,返回對象            return $this->_components[$id] = Yii::createObject($definition);        }    } elseif ($throwException) {//如果拋出異常,則拋出異常        throw new InvalidConfigException("Unknown component ID: $id");    } else {//其他返回null        return null;    }}//註冊一個服務public function set($id, $definition){    if ($definition === null) {//如果該服務的定義為null,則刪除已經執行個體化的服務,返回空,用於登出已經執行個體化的並且儲存過的服務的定義        unset($this->_components[$id], $this->_definitions[$id]);        return;    }    //清空已經執行個體化的服務    unset($this->_components[$id]);    //如果該服務的定義為一個對象,並且是一個可調用的結構    if (is_object($definition) || is_callable($definition, true)) {        // an object, a class name, or a PHP callable        $this->_definitions[$id] = $definition;    } elseif (is_array($definition)) {//如果該服務是一個配置數組        // a configuration array        if (isset($definition['class'])) {//如果有class索引值,則直接註冊為一個服務的定義            $this->_definitions[$id] = $definition;        } else {//是配置數組,但是沒有指定class,則拋出異常            throw new InvalidConfigException("The configuration for the \"$id\" component must contain a \"class\" element.");        }    } else {//什麼都不是,拋出異常,非法註冊服務        throw new InvalidConfigException("Unexpected configuration type for the \"$id\" component: " . gettype($definition));    }}//清空已經執行個體化過的服務和定義,代碼略public function clear($id){}//得到已經執行個體化後的服務,或者得到可用的服務配置public function getComponents($returnDefinitions = true){}//註冊所有的服務,這裡的$components,就是你在config裡寫的 $config['components']值public function setComponents($components){}

那麼ServiceLocator是從什麼時候介入的呢?我們繼續開我們的index.php,注意下面那句話

(new yii\web\Application($config))->run();

我們查看Application

class Application extends \yii\base\Application//繼續追蹤  \yii\base\Applicationabstract class Application extends Module//繼續追蹤  Moduleclass Module extends ServiceLocator
哈,終於找到丫了!!!我們的application 其實就一個服務定位器,我們在設定檔裡配置的components,都是application的這個服務定位器註冊的服務。這下知道為什麼叫做 setComponents這個函數了吧,不明白繼續往下看。

yii 用 set[typename] 的函數來確保屬性的可寫性,在基類 yii\base\Object 的建構函式裡使用了 Yii::configure($this, $config);這個會調用 setComponents 函數註冊服務。

好啦,前後都聯絡上了,yii2使用的依賴注入和服務定位器,就說到這裡。

以上就是yii2 隨筆(七)依賴注入——(4)服務定位器的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.