Formato curto da pergunta
Está dentro das melhores práticas de DDD e OOP injetar serviços em chamadas de método de entidade?
Exemplo de formato longo
Digamos que temos o caso clássico Order-LineItems no DDD, onde temos uma Entidade de Domínio chamada Order, que também atua como Raiz Agregada, e que a Entidade é composta não apenas pelos Objetos de Valor, mas também por uma coleção de Itens de Linha Entidades.
Suponha que desejemos sintaxe fluente em nosso aplicativo, para que possamos fazer algo assim (observando a sintaxe na linha 2, onde chamamos o getLineItems
método):
$order = $orderService->getOrderByID($orderID);
foreach($order->getLineItems($orderService) as $lineItem) {
...
}
Não queremos injetar nenhum tipo de LineItemRepository no OrderEntity, pois isso é uma violação de vários princípios em que posso pensar. Mas, a fluência da sintaxe é algo que realmente queremos, porque é fácil de ler e manter, além de testar.
Considere o seguinte código, observando o método getLineItems
em OrderEntity
:
interface IOrderService {
public function getOrderByID($orderID) : OrderEntity;
public function getLineItems(OrderEntity $orderEntity) : LineItemCollection;
}
class OrderService implements IOrderService {
private $orderRepository;
private $lineItemRepository;
public function __construct(IOrderRepository $orderRepository, ILineItemRepository $lineItemRepository) {
$this->orderRepository = $orderRepository;
$this->lineItemRepository = $lineItemRepository;
}
public function getOrderByID($orderID) : OrderEntity {
return $this->orderRepository->getByID($orderID);
}
public function getLineItems(OrderEntity $orderEntity) : LineItemCollection {
return $this->lineItemRepository->getLineItemsByOrderID($orderEntity->ID());
}
}
class OrderEntity {
private $ID;
private $lineItems;
public function getLineItems(IOrderServiceInternal $orderService) {
if(!is_null($this->lineItems)) {
$this->lineItems = $orderService->getLineItems($this);
}
return $this->lineItems;
}
}
Essa é a maneira aceita de implementar sintaxe fluente nas Entidades sem violar os princípios básicos de DDD e OOP? Para mim, parece bom, pois estamos apenas expondo a camada de serviço, não a camada de infraestrutura (que está aninhada no serviço)