我在Controller,Repository中使用了DI。所有存储库都使用BaseRepository进行扩展。但是,当使用FormType给出错误。 错误消息:Symfony2 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"
SiteBundle/services.yml
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;
}
}
TownController.php
<?php
namespace Personal\AdminBundle\Controller;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Personal\AdminBundle\Controller\BaseController;
use Personal\SiteBundle\Form\TownType;
use Personal\SiteBundle\Entity\Town;
use Personal\SiteBundle\Repository\TownRepository;
/**
* @Route("/town", service="personaladmin.towncontroller")
*/
class TownController extends BaseController
{
protected $_townRepository;
protected $_entityManager;
public function __construct(
TownRepository $townRepository,
EntityManager $entityManager,
TownType $townType
)
{
$this->_townRepository = $townRepository;
$this->_entityManager = $entityManager;
$this->_townType = $townType;
}
/**
* @Route("/list", name="managerv3_town_list")
* @Template()
*/
public function townsAction()
{
$contents = $this->_townRepository->getAll();
return $this->render('PersonalAdminBundle:Town:list.html.twig', array('contents' => $contents));
}
/**
* @Route("/add", name="managerv3_town_add", defaults={"id" = null})
* @Route("/edit/{id}", name="managerv3_town_edit", defaults={"id" = null})
* @Template()
*/
public function townAction(Request $request, $id)
{
if(is_null($id))
{
$content = new Town();
}
else
{
$content = $this->_townRepository->getSingle(array('id' => $id));
}
$form = $this->createForm($this->_townType, $content);
if($request->getMethod() == 'POST')
{
$form->bind($request);
if($form->isValid())
{
$this->_entityManager->persist($content);
$this->_entityManager->flush();
return $this->redirect($this->generateUrl('managerv3_town_list'));
}
}
return $this->render('PersonalAdminBundle:Town:form.html.twig', array('form' => $form->createView()));
}
TownRepository.php
<?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();
}
}
TownType.php
<?php
namespace Personal\SiteBundle\Form;
use Personal\SiteBundle\Repository\CityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Personal\SiteBundle\Entity\City;
class TownType extends AbstractType
{
private $_cityrepository;
public function __construct(CityRepository $cityRepository)
{
$this->_cityrepository = $cityRepository;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', 'text', array(
'label' => 'İlçe Adı',
'horizontal_label_class' => 'col-lg-2',
'horizontal_input_wrapper_class' => 'col-lg-6',
'widget_type' => 'inline'
))
->add('slug')
->add('city', 'entity', array(
'empty_value' => 'Şehir Seçiniz',
'class' => 'PersonalSiteBundle:City',
'query_builder' => function(){
return $this->_cityrepository->getAll();
},
'property' => 'title',
'label' => 'Şehir',
'horizontal_label_class' => 'col-lg-2',
'horizontal_input_wrapper_class' => 'col-lg-3',
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Personal\SiteBundle\Entity\Town'
));
}
/**
* @return string
*/
public function getName()
{
return 'personal_sitebundle_town';
}
}
感谢您的帮助。
你在service.yml定义的“personalsite.baserepository” beeing构建时总是需要“@memcache”服务为第二个参数,你显然在某些时候缺少 – jahller
@jahller对不起,我加BaseRepository.php –
错误消息是因为Doctrine 2试图获得常规的Doctrine Repository。你的BaseRepository不会扩展我认为是设计的DoctrineRepository?如果是这样,则从您的实体中移除存储库类名,以便Doctrine不会尝试使用它们。但我怀疑你确实希望BaseRepository扩展DoctrineRepository。如果是这样,我可以告诉你需要为你的services.yml – Cerad