这是在Symfony2中进行依赖注入的好方法吗?

时间:2015-03-23 14:26:59

标签: php symfony dependency-injection repository-pattern

我注册了我的services.yml文件:

services:
    bb_shop.product_repository:
        class: BB\ShopBundle\Entity\ProductRepository
        factory_service: doctrine.orm.default_entity_manager
        factory_method: getRepository
        arguments: ['BBShopBundle:Product']
    bb_shop.product_service:
        class: BB\ShopBundle\Service\ProductService
        arguments: [@bb_shop.product_repository]

这是我的存储库类:

class ProductRepository extends EntityRepository
{
    public function saveProduct( $p)
    {
        $this->_em->persist($p);
        $this->_em->flush();
    }
}

此我的服务类:

class ProductService {

    protected   $productRepository;
    public  function __construct(ProductRepository $R)
    {
        $this->productRepository =$R;
    }
    public function saveProduct( $p)
    {
        $this->productRepository->saveProduct($p);
    }
} 

这就是我在Controller中调用我的服务的方式:

 $this->get('bb_shop.product_service')->saveProduct($product);

一切顺利。 我的问题是:   1-你能解释一下为什么我需要这2行,即使我在EntityRepository中有EntityManager(由$ this-> _em使用)???

factory_service: doctrine.orm.default_entity_manager
factory_method: getRepository

2 - 这是进行依赖注入的好方法吗?

1 个答案:

答案 0 :(得分:0)

  1. 您需要这两行,因为存储库不会扩展实体管理器。所以基本上你将persist / flush传递给实体管理器。这样就无需将实体管理器暴露给您的服务。您可以注入经理并直接调用persist / flush,但实际上为什么要这么麻烦。

  2. 我一直都在使用你的方法。所以一定很棒。到目前为止,我还没有遇到任何严重的问题。

  3. 您应该了解调用saveProduct的副作用。目前,您的保存产品会刷新实体管理器,因此您最终会保存/更新可能已更改的任何实体(不仅仅是特定产品),因为所有存储库共享同一个管理器。

    这对我来说不是问题。只是需要注意的事情。如果您在单个请求中修改多个产品,那么您可能希望拆分持久性和刷新。所有更改的方式将一次性添加到数据库中。

    class ProductRepository
    {
        public function persist($product) { return $this->_em->persist($product); }
        public function flush($product) { return $this->_em->flush(); }
    

    这种方法的另一个原因是它允许您更换存储库以进行测试。我有基于yaml的存储库,它从yaml文件加载一些实体。存储库公开了简单的find / findAll方法,使编写测试函数变得容易。谁知道,总有一天你可能会决定改用Doctrine 2以外的东西。

    我使用基础存储库类:

    use Doctrine\ORM\EntityRepository as BaseRepository;
    
    class EntityRepository extends BaseRepository
    {
        // Create main entity
        public function createEntity($params = array())
        {
            $entityName = $this->getEntityName();
            return new $entityName($params);
        }
        // Allow null for id
        public function find($id)
        {
            return $id ? parent::find($id) : null;
        }
        /* ==========================================================
         * Persistence
         */
        public function persist($entity) { return $this->getEntityManager()->persist($entity); }
        public function refresh($entity) { return $this->getEntityManager()->refresh($entity); }
        public function detach ($entity) { return $this->getEntityManager()->detach ($entity); }
        public function remove ($entity) { return $this->getEntityManager()->remove ($entity); }
        public function flush()          { return $this->getEntityManager()->flush();          }
        public function clear()          { return $this->getEntityManager()->clear();          
    
        public function getReference($id) { return $this->getEntityManager()->getReference($this->getEntityName(),$id); }