Существует несколько способов доступа к репозиторию объекта в контроллерах или службах Symfony2, каждый из которых имеет свои преимущества и недостатки. Сначала я перечисляю их здесь, а затем спрашиваю, есть ли лучшее решение или это единственные варианты, которые у нас есть, и мы должны выбрать один или несколько, основанный на наших предпочтениях. Я также хочу знать, может ли быть метод 5 (который я начал использовать недавно), и не нарушает никакого правила или каких-либо побочных эффектов.Symfony - Как получить доступ к репозиторию объекта
Основной метод: Использование диспетчера объектов в контроллере или его внедрение в службу, а затем доступ к любому репозиторию, который я хочу. Это основной способ доступа к репозиторию в контроллере или службе.
class DummyController
{
public function dummyAction($id)
{
$em = $this->getDoctrine()->getManager();
$em->getRepository('ProductBundle:Product')->loadProduct($id);
}
}
Но есть некоторые проблемы, связанные с этим методом. Первая проблема заключается в том, что я не могу сделать Ctrl + щелчок, например, функцию loadProduct и перейти непосредственно к ее реализации (если только не существует способа, который я не знаю). Другая проблема заключается в том, что я снова и снова повторяю эту часть кода.
Способ 2: Другой метод - это просто определить получателя в моем сервисе или контроллере для доступа к моему репозиторию.
class DummyService
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function dummyFunction($id)
{
$this->getProductRepository()->loadProduct($id);
}
/**
* @return \ProductBundle\Entity\Repository\ProductRepository
*/
public function getProductRepository()
{
return $this->em->getRepository('ProductBundle:Product');
}
}
Этот метод решает первую проблему и как-то второй, но все же у меня есть повторить все добытчик, что мне нужно в моей службе или контроллере, а также у меня будет несколько добытчиков в моих услугах и контролерах только для доступа к хранилища
Метод 3: Другой способ внедрить хранилище для моей службы, это хорошо, особенно если у нас есть хороший контроль над нашим кодом, и мы не связаны с другими разработчиками, которые инъекционные весь контейнер в свой оказание услуг.
class DummyService
{
protected $productRepository;
public function __construct(ProductRepository $productRepository)
{
$this->productRepository = $productRepository;
}
public function dummyFunction($id)
{
$this->productRepository->loadProduct($id);
}
}
Этот метод решает первую и вторую проблему, но если моя служба большая и он должен иметь дело с большим количеством хранилищ, то это не хорошая идея Inject например, 10 репозитарий моей службы ,
Способ 4: Другим способом является предоставление услуги для переноса всех моих репозиториев и перевода этой службы на другие службы.
class DummyService
{
protected $repositoryService;
public function __construct(RepositoryService $repositoryService)
{
$this->repositoryService = $repositoryService;
}
public function dummyFunction($id)
{
$this->repositoryService->getProductRepository()->loadProduct($id);
}
}
RepositoryService:
class RepositoryService
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* @return \ProductBundle\Entity\Repository\ProductRepository
*/
public function getProductRepository()
{
return $this->em->getRepository('ProductBundle:Product');
}
/**
* @return \CmsBundle\Entity\Repository\PageRepository
*/
public function getPageRepository()
{
return $this->em->getRepository('CmsBundle:Page');
}
}
Этот метод также решает первую и вторую проблему. Но RepositoryService может стать настолько большим, если у нас есть, например, 200 объектов.
Метод 5: Наконец, я могу определить статический метод в каждом объекте, который возвращает свой репозиторий.
class DummyService
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function dummyFunction($id)
{
Product::getRepository($this->em)->loadProduct($id);
}
}
Мои Entity:
/**
* Product
*
* @ORM\Table(name="saman_product")
* @ORM\Entity(repositoryClass="ProductBundle\Entity\ProductRepository")
*/
class Product
{
/**
*
* @param \Doctrine\ORM\EntityManagerInterface $em
* @return \ProductBundle\Entity\ProductRepository
*/
public static function getRepository(EntityManagerInterface $em)
{
return $em->getRepository(__CLASS__);
}
}
Этот метод решает первую и вторую проблему также не нужно определить службу доступа к хранилищам. Я использовал его в последнее время, и пока это лучший метод для меня.Я не думаю, что этот метод нарушит правило сущностей, поскольку он определен в области видимости класса и также является вашим. Но все же я не уверен в этом и не имеет никаких побочных эффектов.
Я использую услуги для своих репозиториев с интерфейсами. Это сокращает количество, которое мой код напрямую связан с Doctrine, когда это действительно не нужно. Все требования к сервису/объекту - это то, что он получает репозиторий, который подходит для интерфейса, а не для получения Doctrine, для получения репозитория (который также не проверяется типом, поэтому не может иметь никаких настраиваемых методов). – qooplmao
Вы определенно НЕ нуждаетесь в доктрине. Это похоже на получение коровы, когда вам нужно только немного молока. – user2268997
у вас есть право @ user2268997 – Roukmoute