Symfony2 FormType依赖项注入

Symfony2 FormType依赖项注入,symfony,doctrine-orm,Symfony,Doctrine Orm,我在控制器、存储库中使用了DI。所有存储库都使用BaseRepository进行扩展。但使用FormType时会出现错误。 错误消息: ContextErrorException: Catchable Fatal Error: Argument 2 passed to Personal\SiteBundle\Repository\BaseRepository::__construct() must be an instance of Memcache, instance of Doctrine\

我在控制器、存储库中使用了DI。所有存储库都使用BaseRepository进行扩展。但使用FormType时会出现错误。 错误消息:

ContextErrorException: Catchable Fatal Error: Argument 2 passed to Personal\SiteBundle\Repository\BaseRepository::__construct() must be an instance of Memcache, instance of Doctrine\ORM\Mapping\ClassMetadata given, called in /home/personal/www/vendor/doctrine/orm/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php on line 75 and defined in /home/personal/www/src/Personal/SiteBundle/Repository/BaseRepository.php line 22
我怎么想?结构如下

AdminBundle/services.yml

personaladmin.towncontroller:
    class: Personal\AdminBundle\Controller\TownController
    arguments: ["@personalsite.townrepository", "@doctrine.orm.entity_manager", "@personalsite.townformtype"]
    parent: "personaladmin.basecontroller"
services:
memcache:
    class: Memcache
    calls:
        - [addServer , [127.0.0.1, 11211]]
personalsite.baserepository:
    class: Personal\SiteBundle\Repository\BaseRepository
    arguments:
        entityManager: "@doctrine.orm.entity_manager"
        memcacheProvider: "@memcache"
personalsite.cityrepository:
    class: Personal\SiteBundle\Repository\CityRepository
    parent: personalsite.baserepository
personalsite.townrepository:
    class: personal\SiteBundle\Repository\TownRepository
    parent: personalsite.baserepository

personalsite.townformtype:
        class: personal\SiteBundle\Form\TownType
        arguments: ["@personalsite.cityrepository"]
SiteBundle/services.yml

personaladmin.towncontroller:
    class: Personal\AdminBundle\Controller\TownController
    arguments: ["@personalsite.townrepository", "@doctrine.orm.entity_manager", "@personalsite.townformtype"]
    parent: "personaladmin.basecontroller"
services:
memcache:
    class: Memcache
    calls:
        - [addServer , [127.0.0.1, 11211]]
personalsite.baserepository:
    class: Personal\SiteBundle\Repository\BaseRepository
    arguments:
        entityManager: "@doctrine.orm.entity_manager"
        memcacheProvider: "@memcache"
personalsite.cityrepository:
    class: Personal\SiteBundle\Repository\CityRepository
    parent: personalsite.baserepository
personalsite.townrepository:
    class: personal\SiteBundle\Repository\TownRepository
    parent: personalsite.baserepository

personalsite.townformtype:
        class: personal\SiteBundle\Form\TownType
        arguments: ["@personalsite.cityrepository"]
BaseRepository.php

    <?php
namespace Personal\SiteBundle\Repository;

use Doctrine\ORM\EntityManager;
use \Memcache;

class BaseRepository
{

    protected $_memcacheProvider;

    /**
     * Connection
     *
     * @var \Doctrine\ORM\EntityManager
     */
    protected $_em;

    public function __construct(
        EntityManager $entityManager,
        Memcache $memcachedProvider
    )
    {
        $this->_memcacheProvider = $memcachedProvider;
        $this->_em  = $entityManager;
    }

}
<?php

namespace Personal\SiteBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Personal\SiteBundle\Repository\BaseRepository;
use Doctrine\ORM\Query;

/**
 * TownRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class TownRepository extends BaseRepository
{
    function getAll( $orderBy = array('town.title' => 'ASC'), $hydrateMode = false )
    {
        $towns =
            $this->_em
                ->createQueryBuilder()
                ->select('town,city')
                ->from('PersonalSiteBundle:Town', 'town')
                ->leftJoin('town.city','city');

        foreach( $orderBy as $oKey => $oVal )
        {
            $towns->orderBy($oKey, $oVal);
        }

        $result = $towns->getQuery()
            ->getResult();

        return $result;
    }

    function getSingle( $where = array(), $hydrateMode = null )
    {
        $content =
            $this->_em
                ->createQueryBuilder()
                ->select('town,city')
                ->from('PersonalSiteBundle:Town', 'town')
                ->leftJoin('town.city', 'city');

        foreach( $where as $condKey => $condVal )
        {
            $parameterKey = 'town_' . $condKey;

            $content->andWhere("town.{$condKey} = :{$parameterKey}");
            $content->setParameter($parameterKey, $condVal);
        }

        $result = $content->getQuery();

        if( $hydrateMode )
            return $result->getSingleResult(Query::HYDRATE_ARRAY);

        return $result->getSingleResult();
    }

}

因此您的基本存储库需要扩展doctrinerepository。条令使用factory getRepository方法创建存储库。要诱使它传递memcache,没有简单的方法。相反,我们需要使用setter注入

use Doctrine\ORM\EntityRepository;
class BaseRepository extends EntityRepository
{
    // No constructor needed

    // Setter injection
    setMemcachedProvider(Memcache $memcachedProvider)
    {
        $this->_memcacheProvider = $memcachedProvider;
    }
在services.yml文件中,删除BaseRepository服务,然后编辑存储库服务:

personalsite.cityrepository:
    class: Personal\SiteBundle\Repository\CityRepository
    factory_service: 'doctrine.orm.default_entity_manager'
    factory_method:  'getRepository'
    arguments:  
        - 'Personal\SiteBundle\Entity\City'
    calls:
         - [setMemcachedProvider, ['@memcache']]
这应该能奏效


我有点好奇为什么要注入memcache。我假设您有一些使用它的自定义存储库代码?教条会忽略它。如果您试图将Doctrine配置为使用memcache,那么这是一个完全不同的过程。

您在service.yml中定义了“personalsite.baserepository”在构建时总是需要“@memcache”服务作为第二个参数,这显然是您在某些方面缺少的point@jahller很抱歉我添加了BaseRepository.php错误消息是因为条令2正在尝试获取常规条令存储库。您的BaseRepository没有扩展DoctrineRepository,我假设它是设计的?如果是这样,那么从实体中删除存储库类名,这样Dority就不会尝试使用它们。但我怀疑您确实希望BaseRepository扩展DoctrineRepository。如果是这样,我可以向您展示服务所需的更改。yml@Cerad是的,我想这样扩展它。如何创建结构?