在symfony2控制器中注入服务

在symfony2控制器中注入服务,symfony,dependency-injection,Symfony,Dependency Injection,如何将服务(我创建的服务)注入控制器? 塞特注射就可以了 <?php namespace MyNamespace; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class MyController extends Controller { public function setMyService(MyService $myService) { $this->myService

如何将服务(我创建的服务)注入控制器? 塞特注射就可以了

<?php
namespace MyNamespace;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{
    public function setMyService(MyService $myService)
    {
        $this->myService = $myService;
    }

    public function indexAction()
    {
        //Here I cannot access $this->myService;
        //Because the setter is not called magically!
    }
}
我正在另一个捆绑包中设置服务:

// Resources/services.yml 
parameters:
   my.service.class: Path\To\My\Service

services:
    my_service:
        class: %my.service.class%
当路由被解析时,服务不会被注入(我知道它不应该被注入)。 我想在yml文件的某个地方,我必须设置:

    calls:
        - [setMyService, [@my_service]]
我没有将此控制器用作服务,它是一个提供请求的常规控制器


编辑:此时,我使用$this->container->get('my_service')获得服务;但是我需要注入它。

如果你想将服务注入你的控制器,你必须


你也可以看看JMSDiExtraBundle的——如果这能解决你的问题的话。但是,由于我将控制器定义为服务,所以我没有尝试过这样做。

如果您不想将控制器定义为服务,可以在kernel.controller事件中添加一个侦听器,以便在执行之前对其进行配置。这样,您就可以使用setter在控制器中注入所需的服务

使用时,您不必将控制器定义为服务(不像@elnur所说的),代码如下:

<?php

namespace MyNamespace;

use JMS\DiExtraBundle\Annotation as DI;
use Path\To\My\Service;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{
    /**
     * @var $myService Service
     *
     * @DI\Inject("my_service")
     */
    protected $myService;

    public function indexAction()
    {
        // $this->myService->method();
    }
}

由于2017年即将结束,Symfony 3或即将推出的Symfony 4没有标签(我认为不应该有),所以这个问题可以用一种本机更好的方式解决

如果您仍在挣扎,不知何故最终出现在这个页面而不是Symfony文档中,那么您应该知道,您不需要将controller声明为service,也不需要将controller声明为service

您需要做的是检查您的
服务。yml

# app/config/services.yml
services:
    # default configuration for services in *this* file
    _defaults:
        # ...
        public: false
如果希望所有服务都是公共的,请将
public:false
更改为
public:true

或显式添加服务并将其声明为公共:

# app/config/services.yml
services:
    # ... same code as before

    # explicitly configure the service
    AppBundle\Service\MessageGenerator:
        public: true
然后在控制器中,您可以获得服务:

use AppBundle\Service\MessageGenerator;

// accessing services like this only works if you extend Controller
class ProductController extends Controller
{
    public function newAction()
    {
        // only works if your service is public
        $messageGenerator = $this->get(MessageGenerator::class);
    }
}
阅读更多:


只需使用
$this->get('my_service')
请阅读本文中的评论:您需要调整路线设置。根据您应该有
\u控制器:我的服务:索引
我的服务是另一个服务,它不是控制器,因此没有索引。indexAction属于MyController,它需要我的_service@Arsham糟糕的是,您必须将您的控制器声明为服务,如文档链接中所示。它不起作用(是的,我尝试过!)。原因是当您登录到一个页面并且它与您的路由匹配时,它不会启动您配置的服务,因此它无法看到您的setter和您尝试注入的服务。尝试将我的控制器设置为服务,但您做得不对。再试一次。如果您遇到问题,请创建一个单独的问题-我们会帮助您。谢谢,我的错误是:我保持了相同的格式,只是将控制器格式更改为服务格式,并且忘记将操作添加到方法名称,因此这起作用:默认值:{u Controller:{name.Of.the.service:indexAction}
use AppBundle\Service\MessageGenerator;

// accessing services like this only works if you extend Controller
class ProductController extends Controller
{
    public function newAction()
    {
        // only works if your service is public
        $messageGenerator = $this->get(MessageGenerator::class);
    }
}