Управление зависимостями в приложениях Zend Framework 2 MVC
Поскольку ServiceLocatorAwareInterface, скорее всего, будет удален из AbstractController в ZF3, зависимости должны вместо этого передаваться через конструктор или методы установки.
Имея это в виду, рассмотрим вариант использования пользователя или контроллера сайта с такими действиями, как регистрация, активация учетной записи, вход в систему, выход из системы и т. Д. Как минимум, для этого потребуется UserService и 2 формы. Добавьте еще несколько связанных действий (удаленная аутентификация, связывание учетных записей и т. Д.), И вы получите 4 или 5 форм.
Передача всех этих зависимостей через конструктор будет в лучшем случае беспорядочной, и, что более важно, для каждого действия обычно требуется только одна форма.
Какой из следующих методов вы считаете лучшим и почему?
Создайте отдельные контроллеры для каждого действия, чтобы каждому контроллеру требовалась только одна форма (в дополнение к услуге). Например, RegistrationController, LoginController, LinkAccountController и т. Д.
- Таким образом, вы получаете много контроллеров.
На заводе для контроллера предоставьте различные формы, в зависимости от того, какое действие запрашивается.
- Построение контроллера становится зависимым от этой фабрики и, более конкретно, от среды запроса (маршрутизация и т. Д.). Вы можете создать контроллер напрямую (для тестирования или чего-либо еще), но тогда вам нужно будет убедиться, что зависимости доступны, и генерировать исключения если не.
Используйте менеджер событий, вызывайте событие в контроллере, когда требуется форма, и позволяйте обработчику событий предоставлять зависимость по требованию.
- Эта техника описана здесь.
- В этом случае ваш контроллер будет зависеть от EventManager, а не от ServiceLocator, что, вероятно, не намного лучше.
Передайте FormElementManager контроллеру и запросите формы у него.
- Не лучше, чем сам SL, скорее всего.
Непосредственно построить формы внутри контроллеров.
- Как это влияет на тестируемость?
- Тот же вопрос будет применяться к обработке контроллера с несколькими службами (вместо форм).
Другой?
Смотрите также:
2 ответа
Во-первых, ServiceLocator не будет удален. Может быть, просто ServiceLocatorAwareInterface.
Как вы сказали, передача FormElementManager является решением, и это действительно лучше, чем передача локатора сервиса. Лично я использую все больше и больше менеджеров плагинов, и они являются хорошим способом решения такой проблемы. Менеджер плагинов отличается от локатора сервисов тем, что позволяет получать только ОДИН тип объектов (формы, гидраторы, входные фильтры...). Конечно, так как родительский локатор службы внедряется в менеджеры плагинов, некоторые люди будут делать трюк для извлечения локатора службы из менеджера плагинов (вот почему я хотел бы удалить в ZF3 локатор служб в менеджерах плагинов и вместо этого иметь конкретная фабрика, где родительский локатор передается для инъекций, хотя это немного усложнит интерфейс фабрики:/...).
Это, с разделением контроллеров на более мелкие контроллеры, должно сделать ваш код чище.
Кстати, вы говорите об аутентификации, но, если вы правильно внедрили сервис аутентификации (или внедрили сервис аутентификации в пользовательский сервис или что-то в этом роде), это значительно уменьшает зависимости в контроллере.
Вы должны думать о проблеме, которую вы пытаетесь решить, как о домене. В домене пользователя есть много форм. Итак, объедините их в хранилище. Хранилище форм будет передано в службу пользователя вместе с другими репозиториями, такими как хранилище сущностей. Затем служба пользователя будет передана в контроллер.
// UserService
public function getForm($name, $id = null)
{
$form = $this->formRepository->find($name);
if ($id !== null) {
$entity = $this->entityRepository->find($id);
$form->bind($entity);
}
return $form;
}