$在Symfony2中的服务中使用时,此对象无法正常工作

时间:2013-10-04 14:38:28

标签: symfony service dependency-injection controller symfony-2.3

我和Symfony一起工作了一段时间,我开始使用控制器作为服务。问题是我不确定我是否了解依赖注入的工作原理。如果我在一个动作中打印$ this,那就完美了。

/**
 * @Route("/testing/this")
 */
public function thisAction(Request $request)
{
    var_dump($this);
    return new Response();
}

响应:

object(Linkedip\WizardBundle\Controller\PaymentsController)[153]
  protected 'object' => null
  protected 'container' => 
    object(appDevDebugProjectContainer)[198]
      protected 'parameterBag' => 
        object(Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag)[48]
          protected 'parameters' => 
            array
              ...

但是,我决定让我的控制器成为一个在其他控制器中使用的服务(我希望在一个控制器中有动作方法和服务方法)。

parameters:
linkedip.controller.payments.class: Linkedip\WizardBundle\Controller\PaymentsController

services:
    payments.controller:
        class:  %linkedip.controller.payments.class%

所以,我添加了一个我打算在其他控制器中使用的新方法,但是当我尝试在新方法中调用$ this时,看看我得到了什么。

/**
 * @Route("/testing/this")
 */
public function thisAction(Request $request)
{
    $paymentsController = $this->get('payments.controller');
    $paymentsController->service();
    return new Response();
}


/**
 *  [SERVICE]
 */
public function service()
{
    var_dump($this);
    return null;
}

响应:

object(Linkedip\WizardBundle\Controller\PaymentsController)[937]
      protected 'object' => null
      protected 'container' => null

为了解决这个问题,我创建了一个setter,将$ this对象直接注入控制器。

/**
 *  [DEPENDENCY INJECTION]
 */
protected $object;
public function setObject($object) { $this->object = $object; }

然后,当我尝试调用其中一项服务时,我需要添加额外的行设置$ this。

$paymentsController = $this->get('payments.controller');
$paymentsController->setObject($this);

在服务方法中,我调用了对象。

$em = $this->object->getDoctrine()->getManager();

这段代码对我有用,但我觉得这是一个肮脏的把戏。我做错了吗?

2 个答案:

答案 0 :(得分:2)

  

[..]但是,我决定让我的控制器成为一个在其他控制器中使用的服务(我想在一个控制器中使用动作方法和服务方法)。

我不同意这种架构选择。你应该让自己的控制器让其他人控制它。然后,如果您仍需要服务,则可以创建一个服务。

答案 1 :(得分:0)

我同意goto,你不应该在一个班级中混合责任。此外,这主要是导致您的问题。回答你的问题:

通过将控制器定义为服务,您没有使用控制器的默认实例化逻辑,因此不会自动注入容器。如果您希望这种情况发生,您应该从依赖注入配置中手动注入容器(或更好:您需要的特定服务)。但是,再次,如果您计划仍然以“常规”方式使用控制器,例如通过定义路线,事情将变得非常混乱,所以我建议,如果您已经在玩DIC,只需创建一个单独的服务并从你的其他控制器中调用它。希望这会有所帮助。