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

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

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

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

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

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

Режим работы

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

$serviceInstance = \Bitrix\Main\DI\ServiceLocator::getInstance()->get(\VendorName\SomeModule\Services\SomeService::class);

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

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

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

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

'someModule.someServiceName' => [
    'className' => \VendorName\SomeModule\Services\SomeService::class,
]
Указать класс сервиса и параметры конструктора

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

'someModule.someServiceName' => [
    'className' => \VendorName\SomeModule\Services\SomeService::class,
    'constructorParams' => ['foo', 'bar'],
]
Указать замыкание-конструктор

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

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

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

'someModule.someServiceName' => [
    'className' => \VendorName\SomeModule\Services\SomeService::class,
],
\VendorName\SomeModule\Contracts\SomeInterface::class => [
    'className' => \VendorName\SomeModule\Services\SomeService::class,
],

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

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

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

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

/bitrix/.settings.phpreturn [
   'services' => [
       'value' => [
           'someServiceName' => [
               'className' => \VendorName\Services\SomeService::class,
           ],
           \VendorName\SomeModule\Contracts\SecondInterface::class => [
               'className' => \VendorName\Services\SecondService::class,
               'constructorParams' => ['foo', 'bar'],
           ],
       ],
       'readonly' => true,
   ],
];

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

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

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

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

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

Через API

Регистрация через API осуществляется методами класса /Bitrix/Main/DI/ServiceLocator.

  • getInstance() получить экземпляр локатора
  • addInstance(string $code, $service) зарегистрировать экземпляр сервиса
  • addInstanceLazy(string $code, $configuration) выполнить ленивую регистрацию с конфигурацией, при которой система создаст сервис только при обращении к нему
  • has(string $code) проверить наличие сервиса
  • get(string $code) получить сервис, метод создает сервис при первом обращении. Если сервиса нет, выбрасывается исключение /Psr/Container/NotFoundExceptionInterface
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!