Skip to content

Instantly share code, notes, and snippets.

@Loupax
Created May 1, 2019 14:21
Show Gist options
  • Save Loupax/fd991daa0c70659f02624f559c0b9812 to your computer and use it in GitHub Desktop.
Save Loupax/fd991daa0c70659f02624f559c0b9812 to your computer and use it in GitHub Desktop.
Create service locator that gets configured using tags
parameters:
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
_instanceof:
App\Service\ServiceInterface:
tags: ['app.service']
App\Controller\:
bind:
$services: '@app.service_locator'
resource: '../src/Controller'
tags: ['controller.service_arguments']
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Service\One;
use App\Service\Two;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ExampleUsageController{
/**
* @Route("/")
*/
public function __invoke(ServiceLocator $services)
{
dd($services->get(Two::class), $services->get(One::class));
return new Response('OK');
}
}
<?php declare(strict_types=1);
namespace App\Di\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
class TaggedServicePass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*/
public function process(ContainerBuilder $container)
{
$services = [];
foreach($container->findTaggedServiceIds('app.service') as $key=>$value){
$services[$key] = new Reference($key);
}
$container
->register('app.service_locator', ServiceLocator::class)
->setArguments([$services])
->addTag('container.service_locator');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment