Blink依賴注入

2018-11-25 22:00 更新

Blink依賴注入與服務(wù)定位器

依賴注入是控制反轉(zhuǎn)(Inversion of Control,縮寫 IoC)的一種實(shí)現(xiàn)方法,是面向?qū)ο缶幊痰囊环N設(shè)計(jì)原則,通過依賴注入, 可以降低類與類之間的耦合,讓代碼的調(diào)試和測(cè)試都變得更加簡(jiǎn)單。

Blink依賴注入

Blink 通過 blink\di\Container 提供 DI 容器功能,它支持構(gòu)造方法注入、Setter屬性注入和回調(diào)注入三種類型的注入方式。

構(gòu)造方法注入

在參數(shù)類型提示的幫助下,DI 容器實(shí)現(xiàn)了構(gòu)造方法注入。當(dāng)容器被用于創(chuàng)建一個(gè)新對(duì)象時(shí),類型提示會(huì)告訴它要依賴什么類或接口。 容器會(huì)嘗試獲取它所依賴的類或接口的實(shí)例,然后通過構(gòu)造器將其注入新的對(duì)象。例如:

class Foo
{
    public function __construct(Bar $bar)
    {
    }
}

$foo = $container->get('Foo');
// 上面的代碼等價(jià)于:
$bar = new Bar;
$foo = new Foo($bar);

Setter 和屬性注入

Setter 和屬性注入是通過對(duì)象配置提供支持的。當(dāng)注冊(cè)一個(gè)依賴或創(chuàng)建一個(gè)新對(duì)象時(shí),你可以提供一個(gè)配置,該配置會(huì)提供給容器用于通過相應(yīng)的 Setter 或?qū)傩宰⑷胍蕾?。例如?/p>

use blink\core\Object;

class Foo extends Object
{
    public $bar;

    private $_qux;

    public function getQux()
    {
        return $this->_qux;
    }

    public function setQux(Qux $qux)
    {
        $this->_qux = $qux;
    }
}

$container->get('Foo', [], [
    'bar' => $container->get('Bar'),
    'qux' => $container->get('Qux'),
]);

PHP 回調(diào)注入

這種情況下,容器將使用一個(gè)注冊(cè)過的 PHP 回調(diào)創(chuàng)建一個(gè)類的新實(shí)例。回調(diào)負(fù)責(zé)解決依賴并將其恰當(dāng)?shù)刈⑷胄聞?chuàng)建的對(duì)象。例如:

$container->set('Foo', function () {
    return new Foo(new Bar);
});

$foo = $container->get('Foo');

服務(wù)定位器

服務(wù)定位器是一個(gè)知道如何提供各種應(yīng)用所需的服務(wù)的對(duì)象。在服務(wù)定位器中,每個(gè)服務(wù)都只有一個(gè)單獨(dú)的實(shí)例(服務(wù)都是單例的), 并通過 ID 唯一地標(biāo)識(shí)。用這個(gè) ID 就能從服務(wù)定位器中得到這個(gè)組件。

Blink 中 blink\core\ServiceLocator 實(shí)現(xiàn)了服務(wù)定位器模式,通過服務(wù)定位器,我們可以很容易的配置這些服務(wù), 并且每個(gè)服務(wù)的實(shí)現(xiàn)都是可以替換的,只要它們實(shí)現(xiàn)的相同的接口。在 Blink 中,整個(gè) application 其實(shí)就是一個(gè)服務(wù)定位器, 它上面掛載了應(yīng)用所需要的全部服務(wù),諸如errorHandler服務(wù),日志服務(wù)、auth服務(wù)等等。

要使用服務(wù)定位器,第一步是要注冊(cè)相關(guān)服務(wù)。服務(wù)可以通過 blink\core\ServiceLocator::bind() 方法進(jìn)行注冊(cè)。 以下的方法展示了注冊(cè)組件的不同方法:

use blink\core\ServiceLocator;

$locator = new ServiceLocator;

// 1\. 通過組件類名
$locator->bind('log', 'blink\log\Logger');

// 2\. 通過配置數(shù)組
$locator->bind('log', [
    'class' => 'blink\log\Logger',
    'targets' => [],
]);

// 3\. 通過匿名函數(shù)
$locator->bind('log', function () {
    return new blink\log\Logger([]);
});

// 4\. 直接使用類的實(shí)例
$locator->bind('log', new blink\log\Logger());

一旦服務(wù)注冊(cè)成功,你可以任選以下兩種方式之一,通過它的 ID 訪問它:

$log = $locator->get('log');

// or

$log = $locator->log;

Blink輔助函數(shù)

創(chuàng)建對(duì)象

Blink 提供了構(gòu)建與 DI 之上的輔助函數(shù) make($type, $params = []),用于快速創(chuàng)建類的實(shí)例并進(jìn)行依賴注入, 通過 make 函數(shù),可以方便的通過對(duì)象配置、類名創(chuàng)建實(shí)例,如:

$object = make([
    'class' => 'blink\log\Logger',
    'prop1' => 'prop2',
]);

// 和

$object = make('blink\log\Logger');

獲取服務(wù)實(shí)例

Blink 提供 app() 方法快速獲取服務(wù)實(shí)例,如下:

$log = app('log');

// 等價(jià)與

$log = app()->get('log');
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)