Yii2 Day 9: 依赖注入实践

目标

Yii1.x常常被批评为强耦合,很难使用第三方库。一般持这样的观点的人会说起Yii1对DI的支持不够,或者说几乎没有。其实我的认为仍是有一些朴素的支持的,好比application就是一个DI,各类组件都是经过 Yii::app()->xxx 的方式建立并引用的,怎么能说没有DI呢?至少实现了一些基本要素:php

  1. 依赖的建立交给了application,而不须要程序员手动在代码中 new来
  2. 维护了一个依赖列表,同一个依赖,在屡次被使用的时候,只须要建立一次

做为富有进取心的框架,Yii2确定不能再继续受这样的批评啦,因而在DI上作了不少工做,达到了DI的几个基本要求html

  1. 建立过程自动化,也就是Ioc,控制反转,即不须要程序员手动new
  2. 依赖的依赖管理,即当依赖又依赖于其余依赖时,可以自动建立其余依赖

关于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

相关文章
相关标签/搜索