сущности и их объекты-значения. Определили интерфейсы их репозиториев. В репах простые методы:
/**
* @throws ProductAlreadyExistException
*/
public function add(Product $product): void;
/**
* @throws ProductDoesNotExistException
*/
public function get(Identity $identity): Product;
/**
* @throws LogicException
*/
public function save(Product $product): void;
/**
* @throws LogicException
*/
public function remove(Product $product): void;
Далее, реализуем эти репозитории, например inMemory:
class InMemoryProductRepository implements ProductRepositoryInterface
{
// реализуем методы ProductRepositoryInterface
}
Или DoctrineRepository:
class DoctrineProductRepository extends ServiceEntityRepository implements ProductRepositoryInterface
{
// реализуем методы ProductRepositoryInterface
}
Для работы с хранилищем через Doctrine для всего этого дела запилили xml mapping наших доменных агрегатов, сущностей и объектов-значений. На удивление - это получилось сделать сведя на нет влияние на доменную логику. Всё взлетело и всё как бы работает. Но! Возникает вопрос, у Doctrine\ORM\EntityRepository есть куча замечательных методов, например:
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
public function findOneBy(array $criteria, ?array $orderBy = null)
// Замечательный magic call:
public function __call($method, $arguments)
public function matching(Criteria $criteria)
Теперь в приложении мы ведь не можем использовать всю эту прелесть и магию доктрины? Потому что все этим методы не определены нашим доменным интерфейсом. И как быть? Особенно интересует возможность делать find через Criteria. Я в тупике🙇🏻♂️
Не наследовать EntityRepository, а инжектить его внутрь своего
А как ты потом свой репозиторий подсунешь в маппинг сущности? Он же должен быть ServiceEntityRepository
Его не надо подсовывать в сущность, ты через getRepository(Entity::class) уже указал, с какой сущностью репа работает.
И впрямь, сейчас попробовал подставить свой InMemoryRepository который не наследует ServiceEntityRepository - всё заработало. Я почему-то думал, что repository-class в маппинге, всегда должен наследовать ServiceEntityRepository
Вообще ServiceEntityRepository выглядит как костыль
А можно по подробнее на этом моменте 🙏🏼
Про что конкретно?
final class DatabaseEmployeeRepository implements EmployeeRepository { /** * @var EntityRepository<Employee> */ private EntityRepository $repo; public function __construct(EntityManagerInterface $em) { $this->repo = $em->getRepository(Employee::class); }
Обсуждают сегодня