2015-05-20 2 views
0

Я создал новую услугу в своем проекте. Эта служба настроена в XML. Я хочу, чтобы пользователь EntityManager, чтобы восстановить данные som в службе, но я не могу «подключить» Doctrine к моей службе. В настоящее время у меня есть этот код:[Symfony 2] Использование 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

Может ли кто-нибудь помочь мне с настройкой моего сервиса? Большое спасибо.

+0

Взгляните на это [сообщение] (http://stackoverflow.com/questions/9172586/the-method- name-must-start-with-or-findby-or-findoneby-undefined-method-sym), это может помочь вам – Maraboc

+0

это сообщение помогло вам? – Maraboc

ответ

3

Ваша реализация путается несколькими путями.

  1. Объект возвращаемый factory-method должен быть того же типа, определенного в атрибуте class - так то, что наследуется от Doctrine\ORM\EntityRepository (это, где ваша «странная ошибка» исходит из)
  2. Это не иметь смысл определить услугу, но затем сделать ее продлением ContainerAware. Весь смысл определения сервисов заключается в том, чтобы вводить зависимости через конфигурацию - не выщипывать их из контейнера во время выполнения.
  3. Противоречивого именования - ваши ссылки службы Site\ProductBundle\Search\SphinxSearch, но ваш класс на самом деле, как пространство имен 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> 

Тогда в классе обслуживания

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