2013-04-02 1 views
1

У меня есть служба домена называется OrderService с saveOrder() способом:Можно ли очистить EntityManager от службы домена?

class OrderService 
{ 
    // ... 

    public function saveOrder(Order $order) 
    { 
     $this->orderRepository->add($order); 
     // $this->entityManager->flush(); 

     $this->notificationService->notifyOrderPlaced($order); 
    } 
} 

saveOrder() добавляет заказ в хранилище (который внутренне вызывает persist() на EntityManager), а затем передает заказ в NotificationService направить соответствующие уведомления (электронная почта, SMS).

Проблема заключается в том, что NotificationService нуждается в идентификаторе заказа для включения в уведомления, заказ еще не имеет идентификатора, поскольку он не сохраняется в БД (идентификатор автоматически создается).

Очевидное решение, похоже, передает EntityManager как зависимость от OrderService и flush() сразу после метода репозитория add(), как в примере выше. Но я всегда не хотел, чтобы службы домена знали об EntityManager, предпочитая, чтобы они разговаривали только с репозиториями или другими службами.

  • Каковы недостатки, если они есть, службы домена, зависящей от EntityManager?
  • Есть ли лучшая альтернатива?

Примечание: Я использую PHP и Doctrine ORM, но я считаю, что одни и те же принципы применимы к Java & Hibernate, а также.

+0

Кто создает 'Заказ'? Кто называет 'saveOrder()'? Является ли 'Order' совокупным корнем или сущностью? Действительно ли это служба домена или более служба уровня приложения? – guillaume31

+0

Контроллер создает 'Order', контроллер вызывает' saveOrder() ',' Order' является агрегированным корнем, и это служба домена. – Benjamin

ответ

0

Вы можете рассмотреть один из этих вариантов (или оба)

  • Сделать это сервис прикладного уровня службы вместо службы доменных имен. Вполне нормально называть свой трекер изменений в службе приложений, так как он должен знать о контексте приложения и прогрессе в текущем прецеденте. Типичные сервисы приложений будут совершать бизнес-транзакцию/задавать отслеживание изменений для сохранения изменений, когда они будут сделаны, поэтому why not call it to generate Id's?

    Если вы обеспокоены тем, что база данных задействована в середине прецедента, возможно, вы найдете эквивалент NHibernate's Guid.Comb strategy, чтобы ваш ORM сгенерировал Id без немедленного ввода INSERT в базу данных.

  • Использование домена. После создания Орден мог сообщить миру, что он был создан. Служба уведомлений обработает событие и отправит соответствующие уведомления. Вы найдете пример этого here (он также включает службу уровня приложения для обслуживания бизнес-транзакции).