7

如何将服务(我创建的服务)注入到我的 Controller 中?一个 setter 注入就可以了。

<?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/routing.yml
myController_index:
    pattern:  /test
    defaults: { _controller: "FooBarBundle:MyController:index" }

我将服务设置在另一个包中:

// 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'); 获得服务 但我需要注入它。

4

4 回答 4

7

如果要将服务注入控制器,则必须将控制器定义为 services

您还可以查看 JMSDiExtraBundle对控制器的特殊处理——如果这可以解决您的问题。但是由于我将控制器定义为服务,所以我没有尝试过。

于 2013-09-03T16:32:37.937 回答
6

使用JMSDiExtraBundle时,您不必将控制器定义为服务(不像@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();
    }
}

我发现这种方法非常好,因为您避免编写__construct()方法。

于 2014-10-21T13:37:57.343 回答
3

由于现在是 2017 年结束,并且没有 Symfony 3 或即将推出的 Symfony 4 的标签(我认为不应该有),这个问题可以用更好的原生方式解决。

如果你还在苦苦挣扎并且不知何故出现在这个页面上而不是在 Symfony 文档中,那么你应该知道,你不需要将控制器声明为服务,因为它已经注册为 one

您需要做的是检查您services.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);
    }
}

阅读更多:

于 2017-09-19T13:02:17.100 回答
0

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

http://symfony.com/doc/current/components/http_kernel/introduction.html#component-http-kernel-kernel-controller

于 2013-09-05T21:59:41.307 回答