So you add an array of parameters without an array of services. You can enter the service through the service:
<services> <service id="notifications_decorator" class="\NotificationsDecorator"> <argument type="service" id="decorator1"/> <argument type="service" id="decorator2"/> <argument type="service" id="decorator3"/> </service> </services>
Or (in my opinion, the best way) tag decorators
services and insert their notifications_decorator
at compile time.
UPDATE: working with Tagged Services
In your case, you need to change your services as follows:
<services> <service id="decorator1" class="\FirstDecorator"> <tag name="acme_decorator" /> </service> <service id="decorator2" class="\SecondDecorator"> <tag name="acme_decorator" /> </service> <service id="decorator3" class="\ThirdDecorator"> <tag name="acme_decorator" /> </service> </services>
Additionally, you must remove the decorators.all
parameter from the <parameters>
section. Then you need to add the sth function as addDectorator
for \NotificationsDecorator
:
class NotificationsDecorator { private $decorators = array(); public function addDecorator($decorator) { $this->decorators[] = $decorator; }
It would be great if you wrote some interface for decorator
and added it as a function type of $decorator
for addDecorator
.
Then you need to write your own compiler pass and ask them about the marked services and add these services to another (similar to doc):
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Reference; class DecoratorCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { if (!$container->hasDefinition('notifications_decorator')) { return; } $definition = $container->getDefinition('notifications_decorator'); $taggedServices = $container->findTaggedServiceIds('acme_decorator'); foreach ($taggedServices as $id => $attributes) { $definition->addMethodCall( 'addDecorator', array(new Reference($id)) ); } } }
Finally, you should add your DecoratorCompilerPass
to Compiler
in your package class, for example:
class AcmeDemoBundle extends Bundle { public function build(ContainerBuilder $container) { parent::build($container); $container->addCompilerPass(new DecoratorCompilerPass()); } }
Good luck