1 追蹤者

服務定位器

服務定位器是一個物件,它知道如何提供應用程式可能需要的所有類型的服務(或元件)。在服務定位器中,每個元件都以單一實例存在,並由 ID 唯一識別。您可以使用 ID 從服務定位器中檢索元件。

在 Yii 中,服務定位器僅僅是 yii\di\ServiceLocator 或其子類別的實例。

在 Yii 中最常用的服務定位器是應用程式物件,可以透過 \Yii::$app 存取。它提供的服務稱為應用程式元件,例如 requestresponseurlManager 元件。您可以透過服務定位器提供的功能輕鬆配置這些元件,甚至將它們替換為您自己的實作。

除了應用程式物件之外,每個模組物件也是一個服務定位器。模組實作了樹狀結構遍歷

要使用服務定位器,第一步是向其註冊元件。元件可以透過 yii\di\ServiceLocator::set() 註冊。以下程式碼示範了註冊元件的不同方式

use yii\di\ServiceLocator;
use yii\caching\FileCache;

$locator = new ServiceLocator;

// register "cache" using a class name that can be used to create a component
$locator->set('cache', 'yii\caching\ApcCache');

// register "db" using a configuration array that can be used to create a component
$locator->set('db', [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=demo',
    'username' => 'root',
    'password' => '',
]);

// register "search" using an anonymous function that builds a component
$locator->set('search', function () {
    return new app\components\SolrService;
});

// register "pageCache" using a component
$locator->set('pageCache', new FileCache);

一旦元件被註冊,您可以使用其 ID 以以下兩種方式之一存取它

$cache = $locator->get('cache');
// or alternatively
$cache = $locator->cache;

如上所示,yii\di\ServiceLocator 允許您像使用元件 ID 的屬性一樣存取元件。當您第一次存取元件時,yii\di\ServiceLocator 將使用元件註冊資訊來建立元件的新實例並傳回它。稍後,如果再次存取該元件,服務定位器將傳回相同的實例。

您可以使用 yii\di\ServiceLocator::has() 來檢查元件 ID 是否已註冊。如果您使用無效的 ID 呼叫 yii\di\ServiceLocator::get(),則會拋出例外。

由於服務定位器通常是使用組態建立的,因此提供了一個名為 components 的可寫入屬性。這允許您一次配置和註冊多個元件。以下程式碼顯示了一個配置陣列,可用於配置具有 dbcachetzsearch 元件的服務定位器(例如應用程式

return [
    // ...
    'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=demo',
            'username' => 'root',
            'password' => '',
        ],
        'cache' => 'yii\caching\ApcCache',
        'tz' => function() {
            return new \DateTimeZone(Yii::$app->formatter->defaultTimeZone);
        },
        'search' => function () {
            $solr = new app\components\SolrService('127.0.0.1');
            // ... other initializations ...
            return $solr;
        },
    ],
];

在上面,有一種替代方法可以配置 search 元件。您可以不用直接編寫 PHP 回呼來建構 SolrService 實例,而是可以使用靜態類別方法來傳回這樣的回呼,如下所示

class SolrServiceBuilder
{
    public static function build($ip)
    {
        return function () use ($ip) {
            $solr = new app\components\SolrService($ip);
            // ... other initializations ...
            return $solr;
        };
    }
}

return [
    // ...
    'components' => [
        // ...
        'search' => SolrServiceBuilder::build('127.0.0.1'),
    ],
];

當您發佈封裝了一些非 Yii 第三方程式庫的 Yii 元件時,這種替代方法是最合適的。您可以使用如上所示的靜態方法來表示建構第三方物件的複雜邏輯,而您的元件使用者只需要呼叫靜態方法來配置元件。

樹狀結構遍歷

模組允許任意巢狀結構;Yii 應用程式本質上是一個模組樹狀結構。由於這些模組中的每一個都是一個服務定位器,因此子模組可以存取其父模組是有道理的。這允許模組使用 $this->get('db') 而不是引用根服務定位器 Yii::$app->get('db')。額外的好處是開發人員可以選擇覆蓋模組中的配置。

從模組檢索服務的任何請求都將傳遞給其父模組,以防模組無法滿足它。

請注意,模組中元件的配置永遠不會與父模組中元件的配置合併。「服務定位器」模式允許我們定義具名服務,但不能假設具有相同名稱的服務使用相同的配置參數。

發現錯字或您認為此頁面需要改進?
在 github 上編輯 !