[Symfony 2]将Doctrine用于服务

时间:2015-05-20 15:02:38

标签: xml symfony doctrine-orm doctrine

我在我的项目中创建了一项新服务。此服务以XML格式配置。 我想使用EntityManager来检索服务中的som数据,但我无法将Doctrine“连接”到我的服务中。 目前,我有这个代码:

的services.xml

<service id="SiteService.search" class="Site\ProductBundle\Search\SphinxSearch" factory-service="doctrine.orm.entity_manager" factory-method="getRepository">
<argument>Site\ProductBundle\Entity\Product</argument>
</service>

SphinxSearch.php

namespace Dada\FilmsBundle\Search;
use Symfony\Component\DependencyInjection\ContainerAware;
class DadaSearch extends ContainerAware{
    //Some stuff
    public function fullNoPrivateByTitle($query){
        //Call $this->getResultsFromId($idlist);
    }
    private function getResultsFromId($idlist){
    $doctrine = $this->container->get('doctrine')->getManager()->getRepository('SiteProductBundle:Product');
    //Rest of the method
    }

使用此代码,我收到一个奇怪的错误。好像Symfony认为我的服务是一种新的学说:

  

未定义的方法'fullNoPrivateByTitle'。方法名称必须开始   与findBy或findOneBy! 500内部服务器错误 -   BadMethodCallException

有人可以帮我配置我的服务吗? 非常感谢。

1 个答案:

答案 0 :(得分:3)

您的实施方式会以一些不同的方式混淆。

  1. factory-method返回的对象必须与class属性中定义的类型相同 - 所以继承自Doctrine\ORM\EntityRepository的内容(这是您的“奇怪错误”即将到来的地方)从)
  2. 定义服务然后使其扩展ContainerAware没有意义。定义服务的重点是通过配置注入依赖关系 - 而不是在运行时从容器中提取它们。
  3. 命名不一致 - 您的服务引用Site\ProductBundle\Search\SphinxSearch,但您的类实际上已命名为Dada\FilmsBundle\Search\DataSearch
  4. 注入EntityRepository有两种选择:在尝试使用工厂时,或使用expression language

    工厂方法应如下所示(假设正确的存储库为ProductRepository

    <service
        id="repository.product"
        class="Site\ProductBundle\Entity\ProductRepository"
        factory-service="doctrine.orm.entity_manager"
        factory-method="getRepository"
    >
        <argument>Site\ProductBundle\Entity\Product</argument>
    </service>
    
    <service id="SiteService.search" class="Site\ProductBundle\Search\SphinxSearch">
       <argument type="service" id="repository.product"/>
    </service>
    

    表达式语法如下所示

    <service id="SiteService.search" class="Site\ProductBundle\Search\SphinxSearch">
       <argument type="expression">service('doctrine.orm.entity_manager').getRepository('ProductBundle:Product')</argument>
    </service>
    

    然后在您的服务类

    <?php
    
    namespace Site\ProductBundle\Search;
    
    class SphinxSearch
    {
        /**
         * @var \Site\ProductBundle\Entity\ProductRepository
         */
        protected $repository;
    
        public function __construct(ProductRepository $repository) {
            $this->repository = $repository;
        }
    
        private function getResultsFromId($idlist) {
            // Do whatever with $this->repository
        }
    }