Yii依賴注入

DI(依賴注入)容器是一個知道如何實例化和配置對象的對象。 Yii提供對它 yii\di\Container 類來提供 DI 容器。

它支持以下幾種注入方式 -

  • Setter方法和屬性注入

  • PHP可調用注入

  • 構造函數注入

  • 控制器動作注入

依賴注入(DI)容器支持構造器使用類型提示的幫助來注入 -

class Object1 {
public function __construct(Object2 $object2) {

}
}
$object1 = $container->get('Object1');
// which is equivalent to the following:
$object2 = new Object2;
$object1 = new Object1($object2);

屬性和 setter 注入需要通過配置支持 -

\_var2; } public function setVar2(MyObject2 $var2) { $this->\_var2 = $var2; } } $container->get('MyObject', \[\], \[ 'var1' => $container->get('MyOtherObject'), 'var2' => $container->get('MyObject2'), \]); ?>

在調用PHP注入的案例中,容器將使用註冊的 PHP 回調構建類的新實例 -

$container->set('Object1', function () {
$object1 = new Object1(new Object2);
return $object1;
});
$object1 = $container->get('Object1');

控制器操作注入是一種依賴注入(DI)類型,在這裏依賴聲明使用類型提示。這是有助於保持 MVC 控制器的超輕量級 -

public function actionSendToAdmin(EmailValidator $validator, $email) {
if ($validator->validate($email)) {
// sending email
}
}

可以使用 yii\db\Container::set() 方法來註冊依賴 -

set('yii\\db\\Connection'); // register an alias name. You can use $container->get('MyObject') // to create an instance of Connection $container->set('MyObject', 'yii\\db\\Connection'); // register an interface // When a class depends on the interface, the corresponding class // will be instantiated as the dependent object $container->set('yii\\mail\\MailInterface', 'yii\\swiftmailer\\Mailer'); // register an alias name with class configuration // In this case, a "class" element is required to specify the class $container->set('db', \[ 'class' => 'yii\\db\\Connection', 'dsn' => 'mysql:host=127.0.0.1;dbname = helloworld', 'username' => 'vladimir', 'password' => '12345', 'charset' => 'utf8', \]); // register a class with configuration. The configuration // will be applied when the class is instantiated by get() $container->set('yii\\db\\Connection', \[ 'dsn' => 'mysql:host=127.0.0.1;dbname = mystudy', 'username' => 'root', 'password' => '', 'charset' => 'utf8', \]); // register a PHP callable // The callable will be executed each time when $container->get('db') is called $container->set('db', function ($container, $params, $config) { return new \\yii\\db\\Connection($config); }); // register a component instance // $container->get('pageCache') will return the same instance each time when it //is called $container->set('pageCache', new FileCache); ?>

使用依賴注入(DI)


第1步 - 在 components 文件夾中創建一個 MyInterface.php 的文件,並使用下面的代碼。

第2步 - 在 components 文件夾中創建兩個文件。

First.php −

"; } } ?>

Second.php −

"; } } ?>

第3步 - 現在,添加一個 actionTestInterface 到控制器 SiteController。

public function actionTestInterface() {
$container = new \yii\di\Container();
$container->set
("\app\components\MyInterface","\app\components\First");
$obj = $container->get("\app\components\MyInterface");
$obj->test(); // print "First class"
$container->set
("\app\components\MyInterface","\app\components\Second");
$obj = $container->get("\app\components\MyInterface");
$obj->test(); // print "Second class"
}

第4步 - 在瀏覽器打開URL地址: http://localhost:8080/index.php?r=site/test-interface ,會看到輸出如下圖所示。

Yii依賴注入

這種方法很方便,因爲我們可以在一個地方設置類,而且其他代碼將自動使用新類。