当前位置:K88软件开发文章中心网站服务器框架Yii 2.0 → 文章内容

依赖注入容器(Dependency Injection Container)

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-26 15:28:56

ction', [ 'dsn' => '...',]);$container->set('app\models\UserFinderInterface', [ 'class' => 'app\models\UserFinder',]);$container->set('userLister', 'app\models\UserLister');$lister = $container->get('userLister');// 等价于:$db = new \yii\db\Connection(['dsn' => '...']);$finder = new UserFinder($db);$lister = new UserLister($finder);实践中的运用当在应用程序的入口脚本中引入?Yii.php?文件时,Yii 就创建了一个 DI 容器。这个 DI 容器可以通过 Yii::$container 访问。当调用 Yii::createObject() 时,此方法实际上会调用这个容器的 yii\di\Container::get() 方法创建新对象。如上所述,DI 容器会自动解决依赖关系(如果有)并将其注入新创建的对象中。因为 Yii 在其多数核心代码中都使用了 Yii::createObject() 创建新对象,所以你可以通过 Yii::$container 全局性地自定义这些对象。例如,你可以全局性自定义 yii\widgets\LinkPager 中分页按钮的默认数量:\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);这样如果你通过如下代码在一个视图里使用这个挂件,它的?maxButtonCount?属性就会被初始化为 5 而不是类中定义的默认值 10。echo \yii\widgets\LinkPager::widget();然而你依然可以覆盖通过 DI 容器设置的值:echo \yii\widgets\LinkPager::widget(['maxButtonCount' => 20]);另一个例子是借用 DI 容器中自动构造方法注入带来的好处。假设你的控制器类依赖一些其他对象,例如一个旅馆预订服务。你可以通过一个构造器参数声明依赖关系,然后让 DI 容器帮你自动解决这个依赖关系。namespace app\controllers;use yii\web\Controller;use app\components\BookingInterface;class HotelController extends Controller{ protected $bookingService; public function __construct($id, $module, BookingInterface $bookingService, $config = []) { $this->bookingService = $bookingService; parent::__construct($id, $module, $config); }}如果你从浏览器中访问这个控制器,你将看到一个报错信息,提醒你?BookingInterface?无法被实例化。这是因为你需要告诉 DI 容器怎样处理这个依赖关系。\Yii::$container->set('app\components\BookingInterface', 'app\components\BookingService');现在如果你再次访问这个控制器,一个?app\components\BookingService?的实例就会被创建并被作为第三个参数注入到控制器的构造器中。什么时候注册依赖关系由于依赖关系在创建新对象时需要解决,因此它们的注册应该尽早完成。如下是推荐的实践:如果你是一个应用程序的开发者,你可以在应用程序的入口脚本或者被入口脚本引入的脚本中注册依赖关系。如果你是一个可再分发扩展的开发者,你可以将依赖关系注册到扩展的引导类中。总结依赖注入和服务定位器都是流行的设计模式,它们使你可以用充分解耦且更利于测试的风格构建软件。强烈推荐你阅读?Martin 的文章,对依赖注入和服务定位器有个更深入的理解。Yii 在依赖住入(DI)容器之上实现了它的服务定位器。当一个服务定位器尝试创建一个新的对象实例时,它会把调用转发到 DI 容器。后者将会像前文所述那样自动解决依赖关系。

上一页  [1] [2] 


依赖注入容器(Dependency Injection Container)