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);

コンポーネントが登録されると、次の2つのいずれかの方法で、そのIDを使用してアクセスできます

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

上記のように、yii\di\ServiceLocator を使用すると、コンポーネントIDを使用してプロパティのようにコンポーネントにアクセスできます。最初にコンポーネントにアクセスすると、yii\di\ServiceLocator はコンポーネント登録情報を使用してコンポーネントの新しいインスタンスを作成し、それを返します。その後、コンポーネントに再度アクセスすると、サービスロケーターは同じインスタンスを返します。

yii\di\ServiceLocator::has() を使用して、コンポーネントIDがすでに登録されているかどうかを確認できます。yii\di\ServiceLocator::get() を無効なIDで呼び出すと、例外がスローされます。

サービスロケーターは 構成 を使用して作成されることが多いため、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コンポーネントを設定する別の方法があります。SolrServiceインスタンスを構築するPHPのコールバックを直接記述する代わりに、以下に示すように、そのようなコールバックを返す静的クラスメソッドを使用できます。

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アプリケーションは本質的にモジュールのツリーです。これらのモジュールのそれぞれがサービスロケーターであるため、子が親にアクセスできるのは理にかなっています。これにより、モジュールはルートサービスロケーターYii::$app->get('db')を参照する代わりに、$this->get('db')を使用できます。追加の利点は、開発者がモジュール内の構成を上書きできるオプションがあることです。

モジュールから取得されるサービスのリクエストは、モジュールがそれを満たすことができない場合、その親に渡されます。

モジュール内のコンポーネントからの構成は、親モジュール内のコンポーネントからの構成とマージされることはありません。サービスロケーターパターンを使用すると、名前付きサービスを定義できますが、同じ名前のサービスが同じ構成パラメーターを使用しているとは限りません。

タイプミスを発見した場合、またはこのページを改善する必要があると思われる場合は?
githubで編集する !