Last active
August 29, 2015 14:25
-
-
Save shengjie/22371421aa290a334840 to your computer and use it in GitHub Desktop.
Auto inject implementation of interface (must tagged with "implementation_inject").
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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