Skip to content

Instantly share code, notes, and snippets.

@shengjie
Last active August 29, 2015 14:25
Show Gist options
  • Save shengjie/22371421aa290a334840 to your computer and use it in GitHub Desktop.
Save shengjie/22371421aa290a334840 to your computer and use it in GitHub Desktop.
Auto inject implementation of interface (must tagged with "implementation_inject").
<?php
/**
* @author: shengjie
* @date: 24/07/15 15:33
* @file: ImplementationInjectPass.php
*/
namespace AppBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
/**
* Example
* In one bundle:
* services:
* id: my_service
* class: MyServiceInterface
* tags:
* - {name: "implementation_inject"}
*
*
* In another bundle:
* services:
* id: my_service_implementation_name_does_not_matter
* class: MyServiceImplNameDoesNotMatter //This class implements interface MyServiceInterface
*
* the result will be "my_service" became an alias for service "my_service_implementation_name_does_not_matter"
*/
class ImplementationInjectPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
* @param ContainerBuilder $container
* @throws \Exception
* @api
*/
public function process(ContainerBuilder $container)
{
$services = $container->findTaggedServiceIds("implementation_inject");
$definitions = $container->getDefinitions();
foreach ($services as $id => $tags) {
$injectDef = $container->getDefinition($id);
$interface = $injectDef->getClass();
/** @var Definition[] $impls */
$impls = [];
foreach ($definitions as $implId => $def) {
if ($def->isPublic() && !$def->isAbstract() && $id != $implId) {
$class = $def->getClass();
if ($class && is_subclass_of($class, $interface)) $impls[] = $implId;
}
}
if (count($impls) > 1) throw new \Exception(
"Multiple implementation for interface $interface found:"
. implode(",", $impls)//array_map
);
if (count($impls) == 0) throw new \Exception("No implementation for interface $interface found!");
$container->removeDefinition($id);
$container->setAlias($id, $impls[0]);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment