Когда я читаю документы о репозиториях, часто приходится работать с сущностями и коллекцией, но в режиме "только для чтения".
Никогда не бывает примеров, в которых у репозиториев есть методы, такие как insertUser(User $user)
или updateUser(User $user)
.
Однако при использовании SOA служба не должна работать с Entity Manager (это право, не так ли?), поэтому:
Из этого обоих вопросов, еще один, должен ли мой сервис когда-либо явно persist()
и flush()
мои сущности?
Да, репозитории обычно используются только для запросов.
Вот как я это делаю. Уровень обслуживания управляет сохранением. Уровень контроллера знает уровень сервиса, но ничего не знает о том, как сохраняются объекты модели и откуда они взяты. Для того, что касается уровня контроллера, требуется, чтобы сервисный уровень сохранялся и возвращал объекты - ему все равно, как это делается на самом деле.
Сам сервисный уровень отлично подходит для понимания уровня сохранения: сущности или менеджеры документов, репозитории и т.д.
Здесь приведен код, чтобы сделать его понятным:
class UserController
{
public function indexAction()
{
$users = $this->get('user.service')->findAll();
// ...
}
public function createAction()
{
// ...
$user = new User();
// fill the user object here
$this->get('user.service')->create($user);
// ...
}
}
class UserService
{
const ENTITY_NAME = 'UserBundle:User';
private $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function findAll()
{
return $this->em->getRepository(self::ENTITY_NAME)->findAll();
}
public function create(User $user)
{
// possibly validation here
$this->em->persist($user);
$this->em->flush($user);
}
}
Если вы посмотрите на шаблон репозитория http://martinfowler.com/eaaCatalog/repository.html,
указано, что репозитории используют "подобный сборке интерфейс".
Позже также написано: "Объекты могут быть добавлены и удалены из репозитория, как они могут из простой коллекции объектов".
Я не говорю, что это библия, но концептуально ничего плохого не видеть в репозитории, как в коллекции, которую вы можете запросить. Но поскольку это коллекция, вы можете добавлять, удалять,... Фактически ObjectRepository должен реализовать Doctrine\Common\Collection:)
С другой стороны, самое главное - не испортить чтение и запись, как говорит CQS. Возможно, поэтому они не позволили прямо так, чтобы избежать злоупотреблений и читать/писать микс.
EDIT: Мне следовало поговорить о flush
. Это должно не быть сделано в самом репозитории, так как это может нарушить последовательность транзакций.
Лучше переместить вызов flush
на то, что обертывает всю логику бизнес-транзакций (командная шина обрабатывает команду f.e?)
Хорошо, как вы получаете свой репозиторий, когда не используете entityManager? В конце концов, объекты не будут сохранены магически без подключения к базе данных, поэтому ваша служба должна каким-то образом знать о каком-либо соединении.
Я не знаю о SOA-сервисах, но в моих глазах это не имеет никакого значения, если вы используете $_em->getRepository()->save($entity)
или $_em->persist($entity)
. С другой стороны, если вы используете флеш в своем репозитории, вы можете получить больше запросов, чем нужно, поскольку ваш репозиторий теперь знает о бизнес-логике.
Я думаю, что есть способ сделать это "путь SOA", но я предполагаю, что он не сохраняет сущности в репозитории.
flush()
. Возможно, флеш-парам для многословия?