Перейти к содержанию

Сервис Локатор

Тему урока можно изучить в новом формате — в документации по Bitrix Framework. В ней улучшена структура, описание, примеры.

Описание

Сервис локатор (локатор служб) - это шаблон проектирования для удобной работы с сервисами приложения. Подробнее можно прочитать в статье.

Идея сервиса в том, что вместо создания конкретных сервисов напрямую (с помощью new), используется специальный объект (сервис локатор), который будет отвечать за создание, нахождение сервисов. Своего рода реестр.

Класс \Bitrix\Main\DI\ServiceLocator реализует интерфейс PSR-11. Доступен с версии main 20.5.400.

Простой пример использования:

$serviceLocator = \Bitrix\Main\DI\ServiceLocator::getInstance();

if ($serviceLocator->has('someService'))
{
    $someService = $serviceLocator->get('someService');
    //...$someService использование сервиса
}

Регистрация сервиса

Регистрация через файлы настроек bitrix/.settings.php

Прежде чем обращаться к сервису его необходимо зарегистрировать и один из способов это использование файлов настроек .settings.php. Все необходимые сервисы перечисляются в секции services.

<?php
// /bitrix/.settings.php
    return [
        //...
        'services' => [
            'value' => [
                'someServiceName' => [
                    'className' => \VendorName\Services\SomeService::class,
                ],                      
                'someGoodServiceName' => [
                    'className' => \VendorName\Services\SecondService::class,
                    'constructorParams' => ['foo', 'bar'],
                ],                      
        ],
    'readonly' => true,
    ],  
//...
    ];

В итоге сервисы будут доступны сразу после инициализации ядра. О том, какие есть способы их описания можно прочитать ниже.

$serviceLocator = \Bitrix\Main\DI\ServiceLocator::getInstance();
$someGoodServiceName = $serviceLocator->get('someGoodServiceName');
$someServiceName = $serviceLocator->get('someServiceName');

Регистрация через файлы настроек модуля {moduleName}/.settings.php

В корне модуля так же может располагаться свой файл .settings.php. И в нём можно описать сервисы, которые принадлежат данному модулю и используются в нём. Семантика аналогична описанию в глобальном bitrix/.settings.php и правилам описания конфигураций.

<?php
// someModule/.settings.php
    return [
    //...
    'services' => [
        'value' => [
            'someModule.someServiceName' => [
            'className' => \VendorName\SomeModule\Services\SomeService::class,
            ],                      
            'someModule.someAnotherServiceName' => [
                'constructor' => static function () {
                    return new \VendorName\SomeModule\Services\SecondService('foo', 'bar');
                },
            ],                      
            'someModule.someGoodServiceName' => [
                'className' => \VendorName\SomeModule\Services\SecondService::class,
                    'constructorParams' => static function (){
                        return ['foo', 'bar'];
                },
            ],                      
        ],
        'readonly' => true,
    ],
    //...
];

Внимание! Сервисы будут зарегистрированы только после подключения модуля. Также советуем именовать сервисы модулей, используя префикс имени модуля, чтобы не возникало проблемы уникальности кодов, например:

 iblock.imageUploader
    disk.urlManager
    crm.entityManager
    crm.urlManager
    someModule.urlManager.

Регистрация через API

Сервисы можно зарегистрировать и через API. Для этого воспользуйтесь методами класса \Bitrix\Main\DI\ServiceLocator

Конфигурация сервиса

Конфигурация описывается в виде массива и подсказывает сервис локатору способ создания объекта. На данный момент есть три способа описания:

  1. Указание класса сервиса. Сервис локатор создаст сервис вызвав new $className.

 'someModule.someServiceName' => [
 'className' => \VendorName\SomeModule\Services\SomeService::class,
]
2. Указание класса сервиса и параметров, которые будут переданы в конструктор. Сервис локатор создаст сервис вызвав new $className('foo', 'bar').

        'someModule.someServiceName' => [
                'className' => \VendorName\SomeModule\Services\SomeService::class,
               'constructorParams' => ['foo', 'bar'],
        ]                      

        'someModule.someServiceName' => [
                'className' => \VendorName\SomeModule\Services\SomeService::class,
                'constructorParams' => static function (){
                return ['foo', 'bar'];
            },
        ]
3. Указание замыкания-конструктора, который должен создать и вернуть объект сервиса.

 'someModule.someAnotherServiceName' => [
            'constructor' => static function () {
                        return new \VendorName\SomeModule\Services\SecondService('foo', 'bar');
                },
        ]