Vla*_*pak 11 php design-patterns facade inversion-of-control symfony
我有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(控制反转)。
如果你真的想玩得开心并进行代码冒险,你可以做这样的事情......
创建一个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。
你能这样做吗
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)
| 归档时间: |
|
| 查看次数: |
20365 次 |
| 最近记录: |