symfony 创建实现ContainerAwareInterface的服务

mepcadol  于 2022-11-25  发布在  其他
关注(0)|答案(6)|浏览(110)

当我扩展ContainerAware或实现ContainerAwareInterface时,服务不调用setContainer。

class CustomService implements ContainerAwareInterface
{
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }
}

如何在没有注入的情况下使用服务中的容器?是否需要将容器对象传递给构造函数或setter?

d4so4syb

d4so4syb1#

在services.yml文件中进行定义

services:
    bundle.service_name: 
        class: ...
        calls:
            - [ setContainer, [ @service_container ] ]
dfty9e19

dfty9e192#

仅实现ContainerAwareContainerAwareInterface是不够的。您必须使用service_container作为参数调用setter注入。**但不建议注入整个容器。**最好只注入您真正需要的服务。

lf3rwulv

lf3rwulv3#

您必须将服务名称放在引号内:

services:
    bundle.service_name: 
        class: ...
        calls:
            - [ setContainer, [ '@service_container' ]]
fiei3ece

fiei3ece4#

这是一个完整实现容器感知服务的示例。

**但请注意,应避免注入整个容器。**最佳做法是只注入所需的组件。有关此主题的更多信息,请参阅Law of Demeter - Wikipedia

为此,此命令将帮助您找到所有可用的服务:

# symfony < 3.0
php app/console debug:container

# symfony >= 3.0
php bin/console debug:container

不管怎样,这是完整的例子。
app/config/services.yml档案:

app.my_service:
    class: AppBundle\Service\MyService
    calls:
        - [setContainer, ['@service_container']]

src/AppBundle/Service/MyService.php中的服务类:

<?php

namespace AppBundle\Service;

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;

class MyService implements ContainerAwareInterface
{
    use ContainerAwareTrait;

    public function useTheContainer()
    {
        // do something with the container
        $container = $this->container;
    }
}

最后是src/AppBundle/Controller/MyController.php中的控制器:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

/**
 * My controller.
 */
class MyController extends Controller
{
    /**
     * @Route("/", name="app_index")
     * @Method("GET")
     */
    public function indexAction(Request $request)
    {
        $myService = $this->get('app.my_service');
        $myService->useTheContainer();

        return new Response();
    }
}
nbysray5

nbysray55#

您还可以使用ContainerAwareTrait来实现ContainerAwareInterface。

1u4esq0p

1u4esq0p6#

您可能希望在所有具有ContainerAwareInterface(基于this answer)的类上自动调用setContainer

# services.yaml
services:
  _instanceof:
    Symfony\Component\DependencyInjection\ContainerAwareInterface:
      calls:
        - [setContainer, ['@service_container']]

相关问题