Yii-dependency-injection

提供:Dev Guides
移動先:案内検索

Yii-依存性注入

DI(依存性注入)コンテナは、オブジェクトのインスタンス化および構成方法を知っているオブジェクトです。 Yiiは* yii \ di \ Containerクラス*を介してDIコンテナを提供します。

次の種類のDIをサポートしています-

  • セッターおよびプロパティインジェクション
  • 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);

プロパティとセッターの注入は、構成を介してサポートされています-

<?php
   use yii\base\Object;
   class MyObject extends Object {
      public $var1;
      private $_var2;
      public function getVar2() {
         return $this->_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()*メソッドを使用して、依存関係を登録できます-
<?php
   $container = new \yii\di\Container;
  //register a class name as is. This can be skipped.
   $container->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 = helloworld',
      'username' => 'vladimir',
      'password' => '12345',
      '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 というファイルを作成します。

<?php
   namespace app\components;
   interface MyInterface {
      public function test();
   }
?>
  • ステップ2 *-componentsフォルダー内に2つのファイルを作成します。
*First.php* -
<?php
   namespace app\components;
   use app\components\MyInterface;
   class First implements MyInterface {
      public function test() {
         echo "First class <br>";
      }
   }
?>
*Second.php* -
<?php
   app\components;
   use app\components\MyInterface;
      class Second implements MyInterface {
      public function test() {
         echo "Second class <br>";
      }
   }
?>

ステップ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 *- *http://localhost:8080/index.php?r = site/test-interface にアクセスすると、以下が表示されます。

DIを使用

この方法は、1か所でクラスを設定でき、他のコードは新しいクラスを自動的に使用するため便利です。