Symfony3,DI,在控制器中注入自定义存储库时出错

时间:2016-03-20 20:05:21

标签: dependency-injection symfony

获得以下异常:

Catchable Fatal Error: Argument 1 passed to AppBundle\Controller\AudienceController::__construct() must be an instance of AppBundle\Repository\AudienceRepository, none given, called in /home/eddy/Projects/tm/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php on line 162 and defined

意思是,我使用自定义存储库将我的控制器定义为构造函数参数,但是或者永远不会传递存储库。我尝试调试到ControllerResolver但无济于事。

[services.yml]
services:
    app.audience_repository:
        class: Doctrine\ORM\EntityRepository
        factory: ["@doctrine.orm.entity_manager", getRepository]
        arguments:
            - AppBundle\Entity\Audience
    app.audience_controller:
        class: AppBundle\Controller\AudienceController
        arguments:
            - "@app.audience_repository"


[AppBundle\Controller\AudienceController.php]
    class AudienceController extends Controller
    {
        /**
         * @var AudienceRepository
         */
        private $repository;

        /**
         * @param AudienceRepository $repository
         */
        public function __construct(AudienceRepository $repository)
        {
            $this->repository = $repository;
        }

[AppBundle\Repository\AudienceRepository]
class AudienceRepository extends EntityRepository
{
    public function save(Audience $audience)
    {
        $this->getEntityManager()->persist($audience);
        $this->getEntityManager()->flush();
    }
}

[AppBundle\Entity\Audience.php]
/**
 * Audience
 *
 * @ORM\Table(name="audience")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\AudienceRepository")
 */
class Audience

我认为这是根据http://php-and-symfony.matthiasnoback.nl/2014/05/inject-a-repository-instead-of-an-entity-manager/对symfony3的修改(请参阅https://stackoverflow.com/a/20348821/30759)并且应该有效,但我一直收到此错误。

Stacktrace:
at ErrorHandler ->handleError ('4096', 'Argument 1 passed to AppBundle\Controller\AudienceController::__construct() must be an instance of AppBundle\Repository\AudienceRepository, none given, called in /home/eddy/Projects/tm/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php on line 162 and defined', '/home/eddy/Projects/tm/src/AppBundle/Controller/AudienceController.php', '23', array()) 
in src/AppBundle/Controller/AudienceController.php at line 23   + 
at AudienceController ->__construct () 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php at line 162   + 
at ControllerResolver ->instantiateController ('AppBundle\Controller\AudienceController') 
in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php at line 81   + 
at ControllerResolver ->instantiateController ('AppBundle\Controller\AudienceController') 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php at line 150   + 
at ControllerResolver ->createController ('AppBundle\Controller\AudienceController::newAction') 
in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerResolver.php at line 73   + 
at ControllerResolver ->createController ('AppBundle\Controller\AudienceController::newAction') 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php at line 76   + 
at ControllerResolver ->getController (object(Request)) 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/TraceableControllerResolver.php at line 46   + 
at TraceableControllerResolver ->getController (object(Request)) 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 127   + 
at HttpKernel ->handleRaw (object(Request), '1') 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php at line 62   + 
at HttpKernel ->handle (object(Request), '1', true) 
in vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php at line 169   + 
at Kernel ->handle (object(Request)) 
in web/app_dev.php at line 30   + 
at require ('/home/eddy/Projects/tm/web/app_dev.php') 
in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/router_dev.php at line 40   + 

非常感谢任何帮助:)

1 个答案:

答案 0 :(得分:2)

在您链接到的文章中("注入存储库而不是实体管理器")他写了关于" normal"我认为你应该注入存储库而不是实体管理器(如果适用)。 :在symfony中,默认情况下控制器不是服务。

基本上有两种选择:

选项1:告诉Symfony您的控制器是服务

由于这有点复杂,我在这里留下这个链接:How to Define Controllers as Services

在这种情况下,您不应该扩展Controller基类,这反过来意味着您不能使用它提供的方法。如果你还没有使用它们,这是可以的,你可以去做。

如果没有(例如你想使用" render"方法),你还必须使用setContainer方法将服务容器注入控制器,并且你做了很多工作才能使用基础控制器再次。这就是为什么我建议使用选项2

选项2:使用Controller类中的辅助方法(我更喜欢这个)

$audienceRepo = $this->getDoctrine()->getRepository(Audience::class);

在这种情况下,您不必将控制器定义为服务,您可以像以前一样使用它。