[Symfony 2]在服务中使用 Doctrine

[Symfony 2]Use Doctrine into a service

我在我的项目中创建了一个新服务。此服务在 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 认为我的服务是一种新的 Doctrine:

Undefined method 'fullNoPrivateByTitle'. The method name must start with either findBy or findOneBy! 500 Internal Server Error - BadMethodCallException

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

您的实施在几个不同方面令人困惑。

  1. factory-method 返回的对象必须与 class 属性中定义的类型相同 - 因此继承自 Doctrine\ORM\EntityRepository 的对象(这是您的 "strange error"来自)
  2. 定义服务然后扩展它没有意义ContainerAware。定义服务的全部意义在于通过配置注入依赖项——而不是在运行时从容器中提取它们。
  3. 命名不一致 - 您的服务引用 Site\ProductBundle\Search\SphinxSearch 但您的 class 实际上命名为 Dada\FilmsBundle\Search\DataSearch

您有两种注入 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>

那么为您服务class

<?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
    }
}