Symfony 如何在我的服务中获取容器

Vla*_*pak 11 php design-patterns facade inversion-of-control symfony

我有项目,在这个项目中,我有很大的自己的服务,它庞大而复杂,有自己的依赖项等......我想为这个服务创建,目的是使用我的服务controllers

$myService = $this->container->get('service_from_my_domain');
Run Code Online (Sandbox Code Playgroud)

我的问题是如何在我的门面内部访问container服务的依赖项。我只知道一种方法 - 是在 yaml 配置中将依赖注入到服务中。
但是还有其他方法可以做到吗?喜欢:

$dependency = Container::getInstance()->get('my_dependency_service');
Run Code Online (Sandbox Code Playgroud)

我找到了这个答案,但是使用全局变量感觉就像回到了过去......

PS:我不想通过 yaml 配置(不是构造函数注入或 setter 注入)注入依赖项,因为我在这里不需要 IoC()。

Mat*_*alo 7

如果你真的想玩得开心并进行代码冒险,你可以做这样的事情......

创建一个Facade类,该类必须在应用程序启动时初始化。因此,在 中app.php,就在该行之后$kernel = new AppKernel('prod', false);进行Facade初始化:

$kernel->boot();
$container = $kernel->getContainer();
\MyBundle\Facade::init($container);
Run Code Online (Sandbox Code Playgroud)

并且,这是该类的代码Facade

<?php

namespace MyBundle;


use Symfony\Component\DependencyInjection\ContainerInterface;

class Facade
{
    /**
     * self|null
     */
    private static $instance = null;

    /**
     * ContainerInterface
     */
    private static $myContainer;

    /**
     * @param ContainerInterface $container
     */
    private function __construct(ContainerInterface $container)
    {
        self::$myContainer = $container;
    }

    /**
     * @param string $serviceId
     *
     * @return object
     * @throws \Exception
     */
    public static function create($serviceId)
    {
        if (null === self::$instance) {
            throw new \Exception("Facade is not instantiated");
        }

        return self::$myContainer->get($serviceId);
    }

    /**
     * @param ContainerInterface $container
     *
     * @return null|Facade
     */
    public static function init(ContainerInterface $container)
    {
        if (null === self::$instance) {
            self::$instance = new self($container);
        }

        return self::$instance;
    }
}
Run Code Online (Sandbox Code Playgroud)

而且,无论您在哪里需要某种服务,都可以通过以下方式创建:

$service = \MyBundle\Facade::create('my_dependency_service');


但是,如果你问我 - 我会创建一个外观服务,它将在构造函数中注入一个容器。您将有一些创建服务的方法 ( Facade::create($serviceId)),它会向容器询问给定的服务 ID。


Rob*_*ert 6

你能这样做吗

services:
     kernel.listener.acme_listener:
          class: Acme\AcmeBundle\EventListener\AcmeListener
          arguments:
                - @service_container
          tags:
                - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
Run Code Online (Sandbox Code Playgroud)

你的听众

use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class AcmeListener
 {
    /**
     * @var Container
     */
     private $container;

    /**
     * Constructor
     *
     * @param Container $container
     */
   public function __construct(Container $container)
    {
        $this->container = $container;
    }

   public function onKernelController(FilterControllerEvent $event)
    {
        $this->container->...
    }
 }
Run Code Online (Sandbox Code Playgroud)

  • 我不需要DI。我需要在没有 DI 的情况下在我的服务中获取容器。 (3认同)
  • 我不想通过 yaml 配置注入依赖项。 (2认同)