2

我在 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();

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

4

2 回答 2

2

[..]但是,我决定让我的控制器成为一种服务,以便在其他控制器中使用(我希望在一个控制器中拥有操作方法和服务方法)。

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

于 2013-10-04T15:03:03.277 回答
0

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

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

于 2013-10-16T08:52:34.960 回答