從百草園到三味書屋 (二)IoC 容器

一句話兒發表於2020-02-10

laravel核心:IOC容器

作用: 容器使得框架各個元件能很好的在一起工作。

在 《從百草園到三味書屋 (一)依賴注入》 中,我們定義了 BillerInterface和BillingNotifierInterface 介面。

//假設我們使用了Stripe來進行支付操作。我們可以將Stripe的支付實現繫結到容器裡,就像這樣
App::bind('BillerInterface', function()
{
    return new StripeBiller(App::make('BillingNotifierInterface'));
});

//注意在我們處理BillingInterface時,我們額外需要一個BillingNotifierInterface的實現,也就是再來一個bind:
App::bind('BillingNotifierInterface', function()
{
    return new EmailBillingNotifier;//可方便切換賬單通知介面的具體實現類
});

//一旦我們使用了容器,切換介面的實現就是一行程式碼的事兒。
class UserController extends BaseController{
    public function __construct(BillerInterface $biller)
    {
        $this->biller = $biller;
    }
}

//想在應用中只例項化某類一次?沒問題,使用singleton方法吧:
App::singleton('BillingNotifierInterface', function()
{
    return new SmsBillingNotifier;
});

你的專案沒有使用Laravel?但你依然可以使用Laravel的IoC容器!只要用Composer安裝了illuminate/container包就可以了。

容器的核心:透過php反射類實現(php反射類,可以知道類的一切資訊)

//依靠這個強大的PHP特性, Laravel的IoC容器可以實現很有趣的功能!考慮接下來這個類
class UserController extends BaseController
{
    public function __construct(StripBiller $biller)
    {
        $this->biller = $biller;
    }
}

分析:
注意這個控制器的建構函式暗示著有一個StripBiller型別的引數。使用反射就可以檢測到這種型別暗示。當Laravel的容器無法解決一個型別的明顯繫結時,容器會試著使用反射來解決。

程式流程類似於這樣的:

  1. 已經有一個StripBiller的繫結了麼?
  2. 沒繫結?那用反射來探測一下StripBiller吧。看看他都需要什麼依賴。
  3. 解決StripBiller需要的所有依賴(遞迴處理)
  4. 使用ReflectionClass->newInstanceArgs()來例項化StripBiller
class UserController extends BaseController
{
    public function __construct(BillerInterface $biller)
    {
        $this->biller = $biller;
    }
}
// 為何需要繫結介面例項
App::bind('BillerInterface','StripBiller');

分析:

  1. 假設我們沒有為BillerInterface做任何繫結, 容器該怎麼知道要注入什麼類呢?

  2. 要知道,interface不能被例項化,因為它只是個約定。如果我們不提供更多資訊的話,容器是無法例項化這個依賴的。

  3. 所以,我們需要明確指出哪個類要實現這個介面 App::bind('BillerInterface','StripBiller');

    原文連結:https://my.oschina.net/zgldh?tab=newest&am...

什麼是反射?

簡易反射連結:部落格:PHP 物件導向 (十一)反射類

本作品採用《CC 協議》,轉載必須註明作者和本文連結
寫的不好,就當是整理下思緒吧。

相關文章