Полный цикл в digital

Service Locator (Локатор служб) в Bitrix

Service Locator, это шаблон проектирования, используемый в разработке программного обеспечения для инкапсуляции процессов, связанных с получением какого-либо сервиса с сильным уровнем абстракции.

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

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

// получаем обьект Service Locator
$serviceLocator = \Bitrix\Main\DI\ServiceLocator::getInstance();
// проверяем, зарегистрирован ли Service Locator
if ($serviceLocator->has('название_service_locator'))
{
    // получаем обьект зарегистрированного Service Locator
    $someService = $serviceLocator->get('название_service_locator');
}

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

Предположим у нас есть класс Item, который распологается в модуле по следующиму пути /local/modules/hmarketing.rest/lib/Get/Item.php.

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

Указать класс сервиса

Service Locator создаст сервис вызвав new $className:

'hmarketing.rest' => [
    'className' => '\\Hmarketing\\Rest\\Get\\Item',
]
Указать класс сервиса и параметры конструктора

Service Locator создаст сервис вызвав new $className('foo', 'bar'):

'hmarketing.rest' => [
    'className' => '\\Hmarketing\\Rest\\Get\\Item',
    'constructorParams' => ['foo', 'bar'],
]
Указать замыкание-конструктор

Замыкание создаст и вернет объект сервиса:

'hmarketing.rest' => [
        'constructor' => static function () {
        return new \Hmarketing\Rest\Get\Item('foo', 'bar');
    }
]
Автоматическое создание объектов

Service Locator может автоматически создавать объекты указанных классов, даже если их нет внутри контейнера:

$serviceInstance = \Bitrix\Main\DI\ServiceLocator::getInstance()->get(
    '\\Hmarketing\\Rest\\Get\\Item'
);

В качестве ключа, который реализует сервис, можно использовать строку:

'hmarketing.rest' => [
    'className' => '\Hmarketing\Rest\Get\Item',
]

В качестве ключа, который реализует сервис, можно использовать имя класса или интерфейса:

\VendorName\SomeModule\Contracts\SomeInterface::class => [
    'className' => '\Hmarketing\Rest\Get\Item',
]

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

Чтобы обратиться к сервису, его нужно зарегистрировать одним из способов.

Через файл настроек bitrix/.settings.php

В Bitrix Framework, файлы .settings.php используются для хранения конфигураций. Они находятся в корне проекта и содержат секции для различных настроек, таких как базы данных, кеширование и сервисы. Service Locator регистрируются в секции services:

/bitrix/.settings.phpreturn [
   'services' => [
       'value' => [
           'hmarketing.rest' => [
               'className' => '\Hmarketing\Rest\Get\Item',
           ]
       ],
       'readonly' => true,
   ],
];

После инициализации ядра сервисы становятся доступны:

$serviceLocator = \Bitrix\Main\DI\ServiceLocator::getInstance();
$someService = $serviceLocator->get('hmarketing.rest');
Через файл настроек модуля moduleName/.settings.php

Файл .settings.php в корне модуля описывает сервисы модуля. Это позволяет модулям иметь свои собственные настройки и сервисы, которые не зависят от глобальных настроек:

moduleName/.settings.phpreturn [
   'services' => [
       'value' => [
           'hmarketing.rest' => [
               'className' => '\Hmarketing\Rest\Get\Item',
           ]
       ],
       'readonly' => true,
   ],
];

Сервисы регистрируются после подключения модуля, используйте префикс имени модуля для уникальности, например disk.urlManager, crm.urlManager.

Через API

Работа с локатором осуществляется через экземпляр класса \Bitrix\Main\DI\ServiceLocator, который можно получить через статический метод getInstance(): object:

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

Проверяем наличие/доступность сервиса через метод has(string $code): bool:

  1. $code имя сервиса
$serviceLocator = \Bitrix\Main\DI\ServiceLocator::getInstance();
// проверяем, зарегистрирован ли Service Locator
if ($serviceLocator->has('hmarketing.rest'))
{

}

Получить сервис, метод создает сервис при первом обращении get(string $code): mixed. Если сервиса нет, выбрасывается исключение /Psr/Container/NotFoundExceptionInterface:

  1. $code имя сервиса
$serviceLocator = \Bitrix\Main\DI\ServiceLocator::getInstance();
$someService = $serviceLocator->get('hmarketing.rest');

Регистрация уже созданного и инициализированного сервиса addInstance(string $code, object $service): void:

  1. $code имя сервиса
  2. $service объект конкретного сервиса
$serviceLocator = \Bitrix\Main\DI\ServiceLocator::getInstance();
$serviceLocator->addInstance('hmarketing.rest', new \Hmarketing\Rest\Get\Items());

Ленивая регистрацию с конфигурацией, при которой система создаст сервис только при обращении к нему addInstanceLazy(string $code, array $configuration): void:

  1. $code имя сервиса
  2. $configuration описание с помощью которого сервис локатор будет создавать сервис
\Bitrix\Main\DI\ServiceLocator::getInstance()->addInstanceLazy('hmarketing.rest', [
    'className' => '\\Hmarketing\\Rest\\Get\\Items',
]);
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!