我们可以通过多种方式访问Symfony2控制器或服务中的实体存储库,这些控制器或服务各有优缺点。首先我在这里列出它们然后询问是否有更好的解决方案或者这些是我们唯一的选择,我们应该根据我们的偏好选择一个或一些。我还想知道方法5(我最近开始使用它)是否良好并且不会破坏任何规则或有任何副作用。
基本方法: 在控制器中使用实体管理器或将其注入服务,然后访问我想要的任何存储库。这是在控制器或服务中访问存储库的基本方法。
class DummyController
{
public function dummyAction($id)
{
$em = $this->getDoctrine()->getManager();
$em->getRepository('ProductBundle:Product')->loadProduct($id);
}
}
但是这个方法存在一些问题。第一个问题是我无法按Ctrl +单击例如loadProduct函数并直接进入其实现(除非有一种我不知道的方法)。另一个问题是我将一遍又一遍地重复这部分代码。
方法2: 另一种方法是在我的服务或控制器中定义一个getter来访问我的存储库。
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');
}
}
这个方法解决了第一个问题,不知何故,第二个问题,但我仍然 重复我在服务或控制器中需要的所有getter,我也会在我的服务和控制器中有几个getter只是为了访问存储库
方法3: 另一种方法是为我的服务注入一个存储库,这很好,特别是如果我们对我们的代码有一个很好的控制,并且我们没有参与将整个Container注入您的服务的其他开发人员。
class DummyService
{
protected $productRepository;
public function __construct(ProductRepository $productRepository)
{
$this->productRepository = $productRepository;
}
public function dummyFunction($id)
{
$this->productRepository->loadProduct($id);
}
}
这个方法解决了第一个和第二个问题,但是如果我的服务很大 它需要处理很多存储库然后它不是一个好主意 注入例如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');
}
}
该方法还解决了第一和第二个问题。但是当我们拥有200个实体时,RepositoryService会变得如此之大。
方法5: 最后,我可以在每个返回其存储库的实体中定义静态方法。
class DummyService
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function dummyFunction($id)
{
Product::getRepository($this->em)->loadProduct($id);
}
}
我的实体:
/**
* 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__);
}
}
这个方法解决了第一个和第二个问题,我也不需要定义一个 服务访问存储库。我最近用过它,到目前为止它是我最好的方法。我不认为这种方法会破坏实体的规则,因为它是在类范围中定义的,也是如此。但我仍然不确定它是否有任何副作用。