Service Locator Yii 2
Service Locator Yii 2

Service Locator

A service locator is an object that knows how to provide all sorts of services (or components) that an application might need. Within a service locator, each component exists as only a single instance, uniquely identified by an ID. You use the ID to retrieve a component from the service locator.

In Yii, a service locator is simply an instance of [[yii\di\ServiceLocator]] or a child class.

Старт! Честный VDS/VPS, на котором «Лунная База» живет уже 20+ лет

Задумываетесь о том, чтобы поднять свой pet-проект, сайт клиента или настроить окружение для разработки? Уже пора подумать, где арендовать железо.

Лунная База хостится на FirstVDS более 20 лет. Мыслей о том, чтобы перебраться на другой хостинг, не было ни разу (хотя опыт работы с другими вариантами, конечно, есть).

Бывали разные ситуации, но они бывают на любом железе. Главное, что нужно понять: здесь нет маркетинговой шелухи и сказок про «мы всё сделаем за вас». Если вы берете VDS — вам дают полный root, возможность накатить любую ОС и не лезут в ваши конфиги.

Если в саппорт написать с вопросом по вашему коду и получить ответ: «Читайте документацию и разбирайтесь сами» или «Обратитесь к профильному специалисту» — это не повод обижаться. Это повод углубить свои знания в DevOps и сайтостроении! Бегите от тех, кто пообещает: «Мы всё чиним и настраиваем абсолютно бесплатно!». Никто никогда не работает «по доброте душевной» в ущерб себе, а бесплатный сыр в администрировании обычно заканчивается сломанной базой данных.

Что по факту: Гибкое масштабирование ядер и RAM, экономия по сравнению с физическими серверами и адекватная панель ispmanager, если она вам нужна.



The most commonly used service locator in Yii is the application object, which can be accessed through \Yii::$app. The services it provides are called application components, such as the request, response, and urlManager components. You may configure these components, or even replace them with your own implementations, easily through functionality provided by the service locator.

Besides the application object, each module object is also a service locator. Modules implement tree traversal.

To use a service locator, the first step is to register components with it. A component can be registered via [[yii\di\ServiceLocator::set()]]. The following code shows different ways of registering components:

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

Once a component has been registered, you can access it using its ID, in one of the two following ways:

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

As shown above, [[yii\di\ServiceLocator]] allows you to access a component like a property using the component ID. When you access a component for the first time, [[yii\di\ServiceLocator]] will use the component registration information to create a new instance of the component and return it. Later, if the component is accessed again, the service locator will return the same instance.

You may use [[yii\di\ServiceLocator::has()]] to check if a component ID has already been registered. If you call [[yii\di\ServiceLocator::get()]] with an invalid ID, an exception will be thrown.

Because service locators are often being created with configurations, a writable property named [[yii\di\ServiceLocator::setComponents()|components]] is provided. This allows you to configure and register multiple components at once. The following code shows a configuration array that can be used to configure a service locator (e.g. an application) with the db, cache, tz and search components:

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;
        },
    ],
];

In the above, there is an alternative way to configure the search component. Instead of directly writing a PHP callback which builds a SolrService instance, you can use a static class method to return such a callback, like shown as below:

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'),
    ],
];

This alternative approach is most preferable when you are releasing a Yii component which encapsulates some non-Yii 3rd-party library. You use the static method like shown above to represent the complex logic of building the 3rd-party object, and the user of your component only needs to call the static method to configure the component.

Tree traversal

Modules allow arbitrary nesting; a Yii application is essentially a tree of modules. Since each of these modules is a service locator it makes sense for children to have access to their parent. This allows modules to use $this->get('db') instead of referencing the root service locator Yii::$app->get('db'). Added benefit is the option for a developer to override configuration in a module.

Any request for a service to be retrieved from a module will be passed on to its parent in case the module is not able to satisfy it.

Note that configuration from components in a module is never merged with configuration from a component in a parent module. The Service Locator pattern allows us to define named services but one cannot assume services with the same name use the same configuration parameters.

Самый честный хостинг за 20+ лет существования Лунной Базы

Задумываешься о том, чтобы поднять свой сайт в Интернете? Уже пора подумать о том, какой хостинг выбрать?

Лунная База хостится 20+ лет на firstDVS. При этом, мыслей о том, чтобы перебраться на другой хостинг не было. (Но, при этом есть опыт работы с другими вариантами.)

Бывали с firstDVS разные ситуации, но, они бывают на всех хостингах. Единственное, что тут важно понять, - это то, что никто ничего тебе не будет впаривать... Но, и работать за тебя тоже никто не станет. Если в саппорт ответили: «Читайте по ссылке и разбирайтесь сами...» или вообще «Обратитесь за помощью к специалисту», - это повод углубить свои знания в области сайтостроения, а не бежать к тем, что пообещают: «Мы всё чиним и всё делаем за своих клиентов абсолютно бесплатно!» Никто никогда ничего ни за кого "по доброте душевной" не делал, не делает и не будет делать!

Старт! MoonВase — A Hot Start on the Internet
Старт! MoonВase — A Hot Start on the Internet
Старт! Menu