依賴注入 IOC容器的實現

因爲 個人框架(框架 請看上一篇)使用了兩套數據源php

一套是http的接口請求方式,一套是直接連接 mysql的方式前端

故而 兩套方式,要是想經過配置化的方式就可以實現 數據源的切換,
進而想到了 依賴注入的方式實現該功能java

 

最先接觸 IOC容器 是因爲以前作 .net的時候,那時候聽別人講這些專業名詞  以爲挺高大上的,不過不知道它的優點在哪。mysql

 

後面深刻了解了以後,因爲 注入的解耦的特性,以及 它的高擴展性  確實很是高深。spring

 

就像 咱們目前作的一個系統,因爲以前用的是mysql直接連的數據源,到如今 數據量龐大的時候,發現了它的數據讀寫瓶頸,但是也很無奈呀。sql

 

想要將數據源移植到 分佈式的微服務架構中, 前端上只作一些簡單的php處理。但是因爲以前的代碼擴展性不好,工程量 很龐大,只能開始重構系統了。api

很是痛苦。數組

 

下面經過user 的 數據添加功能進行操做架構

 

依賴注入框架

 

構造注入 

經過構造方法進行對象注入

public class UserModels
{
    private Db $db;
    // 注入
    public function UserModels($server)
    {
        $this->db=$server;
    }
    
    public function add($data)
    {
        $this->db->add($data);
    }
}

public class UserController
{
    public addUser()
    {
        $user=array();
        Db mysql=new Mysql();
        
        UserModels usermodels=new UserModels(mysql);
        
        usermodels->add($user);
    }
}

 

屬性注入
經過setter 方法進行對象注入

public class UserModels
{
    private Db $db;
    // 注入
    public function setDb($server)
    {
        $this->db=$server;
    }
    public function add($data)
    {
        $this->db->add($data);
    }
}

public class UserController
{
    public addUser()
    {
        $user=array();
        Db mysql=new Mysql();
        
        UserModels usermodels=new UserModels();
        usermodels->setDb(mysql);
        usermodels->add($user);
    }
}

 

 

屬性注入的話,就是當你想要注入該對象就注入 不用在咱們的對象構造的時候就注入其中,會耦合性更低。
不然,若是咱們一個類 使用了多個對象,那豈不是 構造方法的參數 一堆堆的。。

 

接口注入

  接口注入的方式就是經過一個接口進行對象注入

public interface Models
{
    public function initDb($server);
}

public class UserModels implements Models
{
    private Db $db;
    // 注入
    public function initDb($server)
    {
        $this->db=$server;
    }
    public function add($data)
    {
        $this->db->add($data);
    }
}

public class UserController
{
    public addUser()
    {
        $user=array();
        Db mysql=new Mysql();
        
        UserModels usermodels=new UserModels();
        usermodels->initDb(mysql);
        usermodels->add($user);
    }
}

 

 

 

發現,這些注入方式的代碼 仍是很差寫,麻煩,想經過配置的方式,底層實現,而後在具體業務上不須要關心個人數據源。。而後 想到了IOC容器,來實現 自動的依賴注入

java 的spring 框架就是用來作這個事情的。但是 我是php 啊。。怎麼辦咧。。想要本身實現一套 相似的東西。

不想用xml 就用 配置的數組吧。

 

先添加一個配置文件   

Ucontainer.php
<?php
namespace Config;
/**
 * IOC容器配置
 * @author
 */
class Ucontainer
{
    // 
    public static $db = array(
        'UserModels'    => 'Db',// 或者指向  Api
    );


}

 

 

而後添加一個

Ucontainer.php類 來作注入

<?php
namespace Lib;

class UContainer{

    /**
    *@intro 經過配置 獲取 數據源對象
    *@author kinmos 
    *@time 
    *@param 
    *@return
    */
    public static function getDbInstanse($models)
    {
        $dbContainer=\Config\Ucontainer::$db;
        if(isset($dbContainer[$models])&&!empty($dbContainer[$models]))
        {
            $source=str_replace('Models','',$models);
            $classname = "\Http\\Models\\".$dbContainer[$models]."\\".$source;
            return new $classname;
        }
    }
}

 

 

 

這樣 ,在咱們的數據層 。定義的Models 文件夾中添加一個UserModels 文件 

UserModels.php

<?php

namespace Http\Models;
use Lib\UContainer;

class UserModels
{
    private static $classname='UserModels';

    // 獲取用戶列表
    public static function userList($params=array()){
        
        $data=UContainer::getDbInstanse(self::$classname)->userList();

        return $data;
    }
}

 

 

這樣在咱們的Models 裏面的Db  和 Api 文件夾中各自添加各自方式的數據源

Api.User.php

<?php

namespace Http\Models\Api;

class User
{


    public function userList($apiReqData = array())
    {
        $result = array();
        //組裝API請求的數據
        $apiName = 'User.userList'; //接口的名稱
        //請求API,獲得返回的數據(數組格式)
        $resultEntity = httpApiGetData($apiName, $apiReqData);
        
        if ($resultEntity['code'] == 200) {
            $result = $resultEntity['data'];
        }

        

        return $result;
    }
}

 

Db.User.php

<?php

namespace Http\Models\Db;

use Lib\DbTable;

/**
 * 
 */
class User extends DbTable
{
    protected $_name = 'user';

    protected $_primary = 'id';

    protected $_db = 'default';

    /*
    * 構造函數
    */
    public function __construct()
    {
    }

    public function userList($params=array())
    {
        // 查詢全部數據
        $list=$this->getList('1=1');
        return $list;
    }
}

 

 

 

這樣 一個整個簡單的容器就搭建起來了。而後在使用上就簡單了。

namespace Http\Controllers\Demo;

use Http\Models\UserModels;

use Http\Controllers\ActionController;

class IndexController extends ActionController
{
    
    public function index()
    {
        $data=UserModels::userList();
        print_r($data);die;
    }
}

 

 

使用上,只須要調用 Models層的數據,就能夠了。業務上不須要關係到底 從那個數據源中取數據,

 

一樣的道理,若是 須要 添加sqlserver的數據源,一樣的方式 添加一個sqlserver的服務就能夠加以注入

相關文章
相關標籤/搜索