Symfony2在控制器中获取公共服务

时间:2015-06-03 12:41:16

标签: service dependency-injection

很多墨水流过Sf2控制器/容器。我面对以下情况:

app/console container:debug security
...
> 4
[container] Information for service security.token_storage
Service Id    security.token_interface
Class         Symfony\Component\Security\Core\Authentication\Token ...
...
Public        yes

LoginBundle \ DefaultController.php

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
    public function indexAction()
    {
        dump(Controller::get('security.token_storage'));
    ...

显然工作正常。

LoginBundle \ UserUtilsController

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserUtilsController extends Controller
{
     public function getRoleById()
     {
     dump(Controller::get('security.token_storage'));
     ...

抛出: Error: Call to a member function get() on a non-object

Sf2 Book - Service container我找到了:

  

在此示例中,控制器扩展了Symfony的基本控制器,使您可以访问服务容器本身。然后,您可以使用get方法从服务容器中找到并检索my_mailer服务

误解是: - 两个控制器都扩展了基本控制器,它本身扩展了ContainerAware,它实现了设置容器的ContainerAwareInterface。 - 两个控制器都访问相同的公共服务容器。

那么,为什么第二个控制器不起作用呢?

我知道这个问题很老但我不想将控制器作为服务注入,我认为在services.yml中重新声明公共服务是多余的,也是错误的

提前谢谢。

1 个答案:

答案 0 :(得分:0)

我自己找到了答案,我希望每个人都能分享同样的情况...... UserUtilsController不起作用,因为它不以这种方式工作。如果你了解它,Symfony架构很有趣。

LoginBundle \控制器\ UserUtilsController

// For this job we don't need to extends any class..
class UserUtilsController
{
   // but we need a property for injecting the service in it
   private $token;

   // Now let's inject service into our property $token
   public function __construct($token) 
   {
     $this->token = $token;
   } 

   // It's not done but let pretend it is and let's use it
   public function getRoleById()
   {
     ...
     return $this->token->getToken()->getRoles(); 
     ...

services.yml

   #here it's the magic
   services: 
       # this is a new services container 
       user.loggeduser_utils:
            # this is my class (second class)
            class: LoginBundle\Controller\UserUtilsController
            # this is how I feed my _construct argument
            arguments: ["@security.token_storage"]

所以我只是在我的新课程中注入现有服务。

现在,要使用它,我们必须在第一堂课中调用:

LoginBundle \控制器\ DefaultController.php

class DefaultController extends Controller
{
  public function indexAction()
  {
     // because my class is now a service container we call in this way
     $userRoleId = $this->get('user.loggeduser_utils');
     ...

在理解Sf2 DI模型之后,上述解决方案几乎是微不足道的。