服務定位器是一個物件,它知道如何提供應用程式可能需要的所有類型的服務(或元件)。在服務定位器中,每個元件都以單一實例存在,並由 ID 唯一識別。您可以使用 ID 從服務定位器中檢索元件。
在 Yii 中,服務定位器僅僅是 yii\di\ServiceLocator 或其子類別的實例。
在 Yii 中最常用的服務定位器是應用程式物件,可以透過 \Yii::$app
存取。它提供的服務稱為應用程式元件,例如 request
、response
和 urlManager
元件。您可以透過服務定位器提供的功能輕鬆配置這些元件,甚至將它們替換為您自己的實作。
除了應用程式物件之外,每個模組物件也是一個服務定位器。模組實作了樹狀結構遍歷。
要使用服務定位器,第一步是向其註冊元件。元件可以透過 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 的可寫入屬性。這允許您一次配置和註冊多個元件。以下程式碼顯示了一個配置陣列,可用於配置具有 db
、cache
、tz
和 search
元件的服務定位器(例如應用程式)
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 上編輯 !
註冊 或 登入 以發表評論。