I have symfony project and inside this project, I have big own service which is huge and complicated with own dependencies etc...
And I wanna create facade for this service with purpose to use my service in controllers
like:
$myService = $this->container->get('service_from_my_domain');
My question - is how inside my facade I can get access to container
to service's dependencies. I know only 1 way - is to inject dependency into service in yaml config.
But is there another way to do it? Like:
$dependency = Container::getInstance()->get('my_dependency_service');
I've found this answer but using global variable feels like back in time...
PS: I don't want to inject dependency through yaml config (not constructor injection nor setter injection) because I don't need IoC (inversion-of-control) here.
In Symfony, these useful objects are called services and each service lives inside a very special object called the service container. The container allows you to centralize the way objects are constructed. It makes your life easier, promotes a strong architecture and is super fast!
A Service Container (or dependency injection container) is simply a PHP object that manages the instantiation of services (i.e. objects). For example, suppose you have a simple PHP class that delivers email messages. Without a service container, you must manually create the object whenever you need it: Copy.
The Dependency Injection Container in Symfony2 allows components to be injected with their dependencies, and is often used as a Service Locator, which when combined with the DI-container pattern is considered to be an anti-pattern by many.
The service configurator is a feature of the service container that allows you to use a callable to configure a service after its instantiation. A service configurator can be used, for example, when you have a service that requires complex setup based on configuration settings coming from different sources/services.
If you really want to have a fun and do code escapades, you could do something like this...
Create a Facade
class, that must be initialized when the app starts. So, in app.php
, just after the line $kernel = new AppKernel('prod', false);
do the Facade
initialization:
$kernel->boot();
$container = $kernel->getContainer();
\MyBundle\Facade::init($container);
And, here is a code for the Facade
class:
<?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;
}
}
And, wherever you need some service, you create it this way:
$service = \MyBundle\Facade::create('my_dependency_service');
But, if you ask me - I would create a Facade service, that would have a container injected in the constructor.
And you would have some method for service creation (Facade::create($serviceId)
), that would ask the container for given service ID.
can you do like this
services:
kernel.listener.acme_listener:
class: Acme\AcmeBundle\EventListener\AcmeListener
arguments:
- @service_container
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
your Listener
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->...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With