@@ -291,6 +291,13 @@ would cause an exception to be raised for a non-abstract service.
291
291
In order for parent dependencies to resolve, the ``ContainerBuilder `` must
292
292
first be compiled. See :doc: `/components/dependency_injection/compilation `
293
293
for more details.
294
+
295
+ .. tip ::
296
+
297
+ In the examples shown, the classes sharing the same configuration also extend
298
+ from the same parent in PHP. This does not need to be the case though, you can
299
+ extract common parts of similar service definitions into a parent service without
300
+ also extending a parent class in PHP.
294
301
295
302
Overriding Parent Dependencies
296
303
------------------------------
@@ -399,123 +406,12 @@ The ``GreetingCardManager`` will receive the same dependencies as before,
399
406
but the ``NewsletterManager `` will be passed the ``my_alternative_mailer ``
400
407
instead of the ``my_mailer `` service.
401
408
402
- Collections of Dependencies
403
- ---------------------------
404
-
405
- It should be noted that the overridden setter method in the previous example
406
- is actually called twice - once per the parent definition and once per the
407
- child definition. In the previous example, that was fine, since the second
408
- ``setMailer `` call replaces mailer object set by the first call.
409
-
410
- In some cases, however, this can be a problem. For example, if the overridden
411
- method call involves adding something to a collection, then two objects will
412
- be added to that collection. The following shows such a case, if the parent
413
- class looks like this::
414
-
415
- abstract class MailManager
416
- {
417
- protected $filters;
418
-
419
- public function addFilter($filter)
420
- {
421
- $this->filters[] = $filter;
422
- }
423
-
424
- // ...
425
- }
426
-
427
- If you had the following config:
428
-
429
- .. configuration-block ::
430
-
431
- .. code-block :: yaml
432
-
433
- # ...
434
- services :
435
- my_filter :
436
- # ...
437
- another_filter :
438
- # ...
439
-
440
- mail_manager :
441
- abstract : true
442
- calls :
443
- - [addFilter, ["@my_filter"]]
444
-
445
- newsletter_manager :
446
- class : " %newsletter_manager.class%"
447
- parent : mail_manager
448
- calls :
449
- - [addFilter, ["@another_filter"]]
450
-
451
- .. code-block :: xml
452
-
453
- <!-- ... -->
454
-
455
- <services >
456
- <service id =" my_filter" >
457
- <!-- ... -->
458
- </service >
459
-
460
- <service id =" another_filter" >
461
- <!-- ... -->
462
- </service >
463
-
464
- <service id =" mail_manager" abstract =" true" >
465
- <call method =" addFilter" >
466
- <argument type =" service" id =" my_filter" />
467
- </call >
468
- </service >
469
-
470
- <service id =" newsletter_manager"
471
- class =" %newsletter_manager.class%"
472
- parent =" mail_manager"
473
- >
474
- <call method =" addFilter" >
475
- <argument type =" service" id =" another_filter" />
476
- </call >
477
- </service >
478
- </services >
479
-
480
- .. code-block :: php
481
-
482
- use Symfony\Component\DependencyInjection\Definition;
483
- use Symfony\Component\DependencyInjection\DefinitionDecorator;
484
- use Symfony\Component\DependencyInjection\Reference;
485
-
486
- // ...
487
- $container->setDefinition('my_filter', ...);
488
- $container->setDefinition('another_filter', ...);
489
-
490
- $mailManager = new Definition();
491
- $mailManager
492
- ->setAbstract(true)
493
- ->addMethodCall('addFilter', array(
494
- new Reference('my_filter'),
495
- ))
496
- ;
497
- $container->setDefinition('mail_manager', $mailManager);
498
-
499
- $newsletterManager = new DefinitionDecorator('mail_manager');
500
- $newsletterManager
501
- ->setClass('%newsletter_manager.class%')
502
- ->addMethodCall('addFilter', array(
503
- new Reference('another_filter'),
504
- ))
505
- ;
506
- $container->setDefinition('newsletter_manager', $newsletterManager);
507
-
508
- In this example, the ``addFilter `` method of the ``newsletter_manager `` service
509
- will be called twice, resulting in the ``$filters `` array containing both
510
- ``my_filter `` and ``another_filter `` objects. This is great if you just want
511
- to add additional filters to the subclasses. If you want to replace the filters
512
- passed to the subclass, removing the parent setting from the config will
513
- prevent the base class from calling ``addFilter ``.
514
-
515
- .. tip ::
409
+ .. caution ::
516
410
517
- In the examples shown there is a similar relationship between the parent
518
- and child services and the underlying parent and child classes. This does
519
- not need to be the case though, you can extract common parts of similar
520
- service definitions into a parent service without also inheriting a parent
521
- class.
411
+ You can't override method calls. When you defined new method calls in the child
412
+ service, it'll be added to the current set of configured method calls. This means
413
+ it works perfectly when the setter overrides the current property, but it doesn't
414
+ work as expected when the setter appends it to the existing data (e.g. an
415
+ ``addFilters() `` method).
416
+ In those cases, the only solution is to *not * extend the parent service and configuring
417
+ the service just like you did before knowing this feature.
0 commit comments