Last active
May 1, 2016 16:58
-
-
Save bcastellano/272eaf33bf75b02fe63e443c3f602c0e to your computer and use it in GitHub Desktop.
Inject Doctrine repositories to services with compiler pass in Symfony 2
This file contains 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 | |
namespace AppBundle; | |
use AppBundle\DependencyInjection\Compiler\InjectRepositoriesCompilerPass; | |
use Symfony\Component\DependencyInjection\ContainerBuilder; | |
use Symfony\Component\HttpKernel\Bundle\Bundle; | |
class AppBundle extends Bundle | |
{ | |
/** | |
* @param ContainerBuilder $container | |
*/ | |
public function build(ContainerBuilder $container) | |
{ | |
parent::build($container); | |
// add compiler pass | |
$container->addCompilerPass(new InjectRepositoriesCompilerPass()); | |
} | |
} |
This file contains 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 | |
namespace AppBundle\DependencyInjection\Compiler; | |
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | |
use Symfony\Component\DependencyInjection\ContainerBuilder; | |
use Symfony\Component\DependencyInjection\Definition; | |
use Symfony\Component\DependencyInjection\Reference; | |
class InjectRepositoriesCompilerPass implements CompilerPassInterface | |
{ | |
/** | |
* {@inheritDoc} | |
*/ | |
public function process(ContainerBuilder $container) | |
{ | |
// find tagged services | |
$services = $container->findTaggedServiceIds('doctrine.repository'); | |
// for each service tagged inject repositories | |
foreach ($services as $key => $tags) { | |
// get tagged service | |
$definition = $container->getDefinition($key); | |
foreach ($tags as $tag) { | |
// replace each argument specified by tag | |
$this->replaceArgument($container, $definition, $tag); | |
} | |
} | |
} | |
/** | |
* Replaces arguments by entity repositories | |
* | |
* @param ContainerBuilder $container | |
* @param Definition $definition | |
* @param array $tag | |
* - argument <int> Argument to replace position. Mandatory | |
* - entity_manager <string> Service name for entity manager to use. Optional | |
* - repository <string> Name for repository service. Optional | |
*/ | |
protected function replaceArgument(ContainerBuilder $container, Definition $definition, array $tag) | |
{ | |
// get object class as service argument | |
$entityClass = $definition->getArgument($tag['argument']); | |
// get entity manager service from tag or parameters | |
$emServiceName = (isset($tag['entity_manager']) ? $tag['entity_manager'] : $container->getParameter('default_entity_manager_service')); | |
if (isset($tag['repository'])) { | |
// if repository is setted, then create repository as service | |
$repositoryClass = $container->getParameter('default_repository_class'); | |
// get repository to replace | |
$dmDefinition = (new Definition($repositoryClass, [$entityClass])) | |
->setFactory([ | |
new Reference($emServiceName), | |
'getRepository' | |
]); | |
// create repository as service | |
$container->setDefinition($tag['repository'], $dmDefinition); | |
// get repository service reference | |
$replacedArgument = new Reference($tag['repository']); | |
} else { | |
// get repository to replace | |
$replacedArgument = (new Definition(null, [$entityClass])) | |
->setFactory([ | |
new Reference($emServiceName), | |
'getRepository' | |
]); | |
} | |
$definition->replaceArgument($tag['argument'], $replacedArgument); | |
} | |
} |
This file contains 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
parameters: | |
# mandatory parameter for doctrine entity manager | |
default_entity_manager_service: doctrine.orm.default_entity_manager | |
# optional parameter to create repositories as shared services | |
default_repository_class: Doctrine\ORM\EntityRepository | |
services: | |
# example 1 | |
app_bundle.user.manager: | |
class: AppBundle\Model\Manager\UserManager | |
arguments: ["AppBundle:User"] | |
tags: | |
- { name: doctrine.repository, argument: 0 } | |
# example 2 | |
app_bundle.post.manager: | |
class: AppBundle\Model\Manager\PostManager | |
arguments: ["AppBundle:Post"] | |
tags: | |
- { name: doctrine.repository, argument: 0, entity_manager: doctrine.orm.default_entity_manager, repository: app_bundle.post.repository } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment