使用Yii2依賴注入簡化開發

本文代碼

https://github.com/xialeistudio/yii2-di-demophp

什麼是依賴注入(DI)?

對象由框架來建立而不是程序員經過 new 建立。跟IoC差很少一個意思。git

爲何要有依賴注入?

  1. 解耦。調用方再也不經過 new 運算符實例化被調用對象,而經過框架(IoC容器)建立以後注入進來。解除了調用者與被調用者之間的依賴。
  2. 有利於面向接口編程。我的認爲OOP程序設計最重要的就是面向接口(面向抽象)編程。由於有了第1步的關係,調用者只須要依賴接口類型而不用依賴實現類型,提升了程序的擴展性。

Yii2的依賴注入

Yii2經過 yiidiContainer 提供DI容器特性。目前支持一下4種方式注入:程序員

  1. 構造方法注入
  2. 方法注入
  3. Setter和屬性注入
  4. PHP回調注入

註冊依賴關係

  1. 經過容器的 set 方法注入
  2. 經過配置文件注入(推薦)

依賴注入實戰

  1. 打開終端,執行如下命令初始化項目:github

    composer create-project --prefer-dist yiisoft/yii2-app-basic basic
  2. 聲明接口業務類 appservicesUserServiceweb

    <?php
    namespace app\services;
    
    interface UserService
    {
        public function show($id);
        
        public function all();
    }
  3. 接口實現文件 appservicesimplUserServiceImplnpm

    <?php
    namespace app\services\impl;
    
    use app\services\UserService;
    
    class UserServiceImpl implements UserService
    {
        private $users = [
            ['id' => 1, 'name' => 'xialei'],
            ['id' => 2, 'name' => 'zhangsan'],
        ];
    
        public function show($id)
        {
            foreach ($this->users as $user) {
                if ($user['id'] == $id) {
                    return $user;
                }
            }
            return null;
        }
    
        public function all()
        {
            return $this->users;
        }
    }
  4. 註冊依賴關係 config/web.php編程

    <?php
    
    use app\services\UserService;
    use app\services\impl\UserServiceImpl;
    
    $params = require __DIR__ . '/params.php';
    $db = require __DIR__ . '/db.php';
    
    $config = [
        'id' => 'basic',
        'basePath' => dirname(__DIR__),
        'bootstrap' => ['log'],
        'aliases' => [
            '@bower' => '@vendor/bower-asset',
            '@npm' => '@vendor/npm-asset',
        ],
        'container' => [
            'definitions' => [
                UserService::class => UserServiceImpl::class
            ]
        ],
        'components' => [
            'request' => [
                // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
                'cookieValidationKey' => '0xGrStOOZE2oXxNNiu-o2eYovJ_Ia1Dk',
            ],
            'response' => [
                'format' => 'json'
            ],
            'errorHandler' => [
                'errorAction' => 'site/error',
            ],
            'urlManager' => [
                'enablePrettyUrl' => true,
                'showScriptName' => false,
                'rules' => [
                ],
            ],
        ],
    ];
    
    if (YII_ENV_DEV) {
        // configuration adjustments for 'dev' environment
        $config['bootstrap'][] = 'debug';
        $config['modules']['debug'] = [
            'class' => 'yii\debug\Module',
            // uncomment the following to add your IP if you are not connecting from localhost.
            //'allowedIPs' => ['127.0.0.1', '::1'],
        ];
    
        $config['bootstrap'][] = 'gii';
        $config['modules']['gii'] = [
            'class' => 'yii\gii\Module',
            // uncomment the following to add your IP if you are not connecting from localhost.
            //'allowedIPs' => ['127.0.0.1', '::1'],
        ];
    }
    
    return $config;
  5. 添加控制器 appcontrollersUserControllerjson

    <?php
    
    namespace app\controllers;
    
    use app\services\UserService;
    use yii\base\Module;
    use yii\web\Controller;
    use yii\web\NotFoundHttpException;
    
    class UserController extends Controller
    {
        private $userService;
    
        public function __construct(string $id, Module $module, UserService $userService, array $config = [])
        {
            $this->userService = $userService;
            parent::__construct($id, $module, $config);
        }
    
        public function actionShow($id)
        {
            $user = $this->userService->show($id);
            if (empty($user)) {
                throw new NotFoundHttpException('用戶不存在');
            }
            return $user;
        }
        
        public function actionAll()
        {
            return $this->userService->all();
        }
    }
  6. 運行測試服務器bootstrap

    ./yii serve/index
  7. 訪問用戶列表接口 http://localhost:8080/user/allapi

    [{
        "id": 1,
        "name": "xialei"
    }, {
        "id": 2,
        "name": "zhangsan"
    }]
  8. 訪問查看用戶接口 http://localhost:8080/user/show?id=1

    {
        "id": 1,
        "name": "xialei"
    }

寫在最後

如你所見,Yii2自帶的IoC容器使用起來仍是挺方便的,觀測了Yii 配置優於編碼 的思想,Yii的組件基本上均可以在配置文件中進行配置而不須要手動編碼。

靈活使用DI可使咱們從依賴關係中解脫出來,專一於業務邏輯。

固然,業務邏輯的組織也是一個很大的研究課題,有興趣的能夠去看看 DDD(領域驅動設計)

相關文章
相關標籤/搜索