symfony - Symfony2, autoload service in service -
question simple but... have main service:
class managerone {}
and have several services want use in main service:
class serviceone{} class servicetwo{} class servicethree{} class servicefour{} ...
each named (in services.yml)
service.one service.two service.three service.four ...
locations of services different, not in 1 folder (but don't think it's huge trouble custom autoloader).
regarding manual can inject them via __construct() in main service (managerone) if got 20 such services need injected? or use need. describe them in services simple inject? o.o think it's not idea so.... can inject container , that's it. but! everywhere people saying inject container worst solution.
what want. need method managerone service load service need 'service.name' or 'path' checker 'service exist'.
you use service tagging , tag each service want use in managerone
class. , either use constructor dependency injection or method injection.
example:
first of need compiler pass collect tagged services:
namespace ...\dependencyinjection\compiler; use symfony\component\dependencyinjection\compiler\compilerpassinterface; use symfony\component\dependencyinjection\reference; use symfony\component\dependencyinjection\containerbuilder; class examplepass implements compilerpassinterface { public function process(containerbuilder $container) { if (!$container->hasdefinition("manager.one")) { return; } $services = array(); foreach ($container->findtaggedserviceids('managed_service') $serviceid => $tag) { $alias = isset($tag[0]['alias']) ? $tag[0]['alias'] : $serviceid; // flip, because want tag aliases (= type identifiers) keys $services[$alias] = new reference($serviceid); } $container->getdefinition('manager.one')->replaceargument(0, $services); } }
then need add compiler pass bundle class:
namespace example\examplebundle; use symfony\component\httpkernel\bundle\bundle; use symfony\component\dependencyinjection\containerbuilder; use ...\dependencyinjection\compiler\examplepass; class examplebundle extends bundle { public function build(containerbuilder $container) { parent::build($container); $container->addcompilerpass(new examplepass()); } }
now can use services:
# services.yml manager.one: class: managerclass arguments: - [] # replaced our compiler pass services.one: class: serviceone tags: - { name: managed_service, alias: service_one } services.two: class: servicetwo tags: - { name: managed_service, alias: service_two }
but caution if manager, service classes automatically created. if performance drawback pass service ids (not reference) management class. add @service_container
second argument , create service needed.
Comments
Post a Comment