Сегодня мы поговорим как устроен самый главный компонент Zend Framework 3, это сервис-менеджер. Этот компонент является развитием реестра из 1-й версии фреймворка. Что же представляет современный реестр? По свой сути это все тот же реестр который был в первой версии, теперь там хранятся только объекты, которые можно извлекать при необходимости. Главная особенность заключается в том, что по умолчанию сервис-менеджер будет возвращать один и тот же экземпляр объекта, хотя есть возможность каждый раз создавать новый экземпляр. Если в момент обращения объект не был создан, то он создается автоматически. Вообще все объекты фремворка так или иначе создаются через сервис-менеджер, будь то контроллер, или сервис, или помощники с плагинами.
Для работы с фреймворком программист должен понимать для чего нужен паттерн проектирования «фабрика», т.к. этот тип паттерна широко используется и рекомендуется производителем. О «фабрике» можно почитать в википедии.
Обычно все настройки сервис-менеджера хранятся в конфигурационных файлах пакетов или самого приложения, и представляют собой обычный ассоциативный массив.
…..
'service_manager' => [
'services' => [],
'invokables' => [],
'factories' => [],
'abstract_factories' => [],
'delegators' => [],
'aliases' => [],
'initializers' => [],
'lazy_services' => [],
'shared' => [],
],
….
В какой массив заносить тот или иной объект зависит от его назначения и принципа работы. Наиболее распространенные типы это 'invokables', 'factories', 'aliases', их опишем подробнее. Итак, объект может быть самодостаточным, и работать сам по себе, а может работать только при помощи другого, например, с соединением с базой данных, т.е. зависеть от других. Как правило самодостаточный объект не имеет конструктора, т.к. для работы не нужны внешние данные, этот объект указывается в 'invokables', сервис-менеджер просто создает его и возвращает как есть. Для более сложных используется промежуточный объект, «фабрика», которую вызывает сервис-менеджер, внутри нее извлекаются нужные внешние данные и зависимости, это передается в конструктор, и мы получаем уже полностью инициализированный наш объект, внутри которого уже все что нам нужно для работы. Следует обратить внимание на то, что созданный объект ничего не знает о других, которые передаются ему в конструктор.
Пример из пакета нашего Statpage,
….
Namespace Mf\Statpage;
….
service_manager' => [
'factories' => [
Service\Statpage::class => Service\Factory\StatpageFactory::class,
Service\GetControllersInfo::class => Service\Factory\GetControllersInfoFactory::class,
Service\GetMap::class => Service\Factory\GetMapFactory::class,
],
],
…..
Ключ массива, это полное имя нашего объекта, значение полное имя объекта «фабрики», которая генерирует наш объект, передавая в конструктор все необходимые данные.
Если нам потребуется сервис Mf\Statpage\Service\Statpage::class в нашем приложении, то в нужной «фабрике», например, контроллера, будет иметь код:
namespace Mf\Statpage\Controller\Factory;
use Mf\Statpage\Service\Statpage;
.....
class IndexControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$connection=$container->get('ADO\Connection');
$statpage_service=$container->get(Statpage::class);
return new $requestedName( $connection,$statpage_service);
}
}
….
В контроллер 2-м параметром будет передан экземпляр Mf\Statpage\Service\Statpage::class. Согласитесь, это очень удобно. Некоторый дискомфорт вызывает то, что нужно помнить длинное имя нашего объекта. Что бы и это упростить, используются «псевдонимы», как вы уже догадались, для этого используется 'aliases', настройка этой секции проста, ключ массива, это имя псевдонима, а значение - полное имя самого объекта, для каждого объекта можно создавать несколько псевдонимов. Например, $connection=$container->get('ADO\Connection'); использует псевдоним 'ADO\Connection', который указан в пакете ADO.
Аналогично устроена конфигурация контроллеров приложения, так же указывается типы объектов, «фабрики» и псевдонимы.
Другие элементы сервис-менеджера довольно сложны для понимания, например, «абстрактная фабрика» - создается объект на основе специальных конфигураций, например, кеширование, нам не нужно задумываться какой объект нам инициализировать, в конфигурации мы просто пишем тип адаптера, где хранить кеш, и инициализация произойдет автоматически, грубо говоря мы не знаем какой именно объект будет создан. Все типы объектов описаны в документации производителя.
Как видите программирование сайта сложная и кропотливая работа профессионального веб программиста. Каждый наш сайт состоит из переплетения сложных объектов, заставляющих сайт работать так, как хочет заказчик. Обращаясь в студию "Мастер Флеш", вы получите профессиональный сайт.
