I have many services which differ very little - swiftmailer services:
swiftmailer:
default_mailer: default
mailers:
default:
url: '%env(CONFIG__PARAMETERS__MAILER_URL)%'
spool:
type: '%swiftmailer.spool.type%'
spool_act:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_ACT)%'
spool:
type: '%swiftmailer.spool.type%'
spool_bbi:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_BBI)%'
spool:
type: '%swiftmailer.spool.type%'
spool_can:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_CAN)%'
spool:
type: '%swiftmailer.spool.type%'
spool_ffi:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_FFI)%'
spool:
type: '%swiftmailer.spool.type%'
spool_flip:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_FLIP)%'
spool:
type: '%swiftmailer.spool.type%'
spool_hscg:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_HSCG)%'
spool:
type: '%swiftmailer.spool.type%'
spool_ibn:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_IBN)%'
spool:
type: '%swiftmailer.spool.type%'
spool_pci:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_PCI)%'
spool:
type: '%swiftmailer.spool.type%'
spool_vop:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_VOP)%'
spool:
type: '%swiftmailer.spool.type%'
spool_vue:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_VUE)%'
spool:
type: '%swiftmailer.spool.type%'
no_spool_act:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_ACT)%'
no_spool_bbi:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_BBI)%'
no_spool_can:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_CAN)%'
no_spool_ffi:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_FFI)%'
no_spool_flip:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_FLIP)%'
no_spool_hscg:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_HSCG)%'
no_spool_ibn:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_IBN)%'
no_spool_pci:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_PCI)%'
no_spool_vop:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_VOP)%'
no_spool_vue:
url: '%env(CONFIG__PARAMETERS__MAILER_URL_VUE)%'
So there is probably 16 services. I need to get them by code like VOP, VUE, etc during execution, just before sending mail.
Service id looks like this: swiftmailer.mailer.spool_act
So simplest way would be to create one class with all those 16 injected services. But does not look nice.
Could split them into 2 classes - spool and no spool. Then each would have 8 injections. Still not nice, plus there is no guarantee that there will be no need for more later.
One guy suggested tagging services, and inject collection by tags from here: https://symfony.com/doc/current/service_container/tags.html#reference-tagged-services
I have tried but still not found good solution without overengineering. One idea is to create 16 classes and into each of them inject the swifmailer service like swiftmailer.mailer.spool_act. And then in my class have send method which calls send from swiftmailer.mailer.spool_act. And then tag my created services and inject as in that symfony documentation with iterator. But that looks like doing simple thing too complicated way and with too much code.
What is better solution? There should have been similar problems really for other people. I dont get how I cannot find.
Update
I have tried by one answer with instnacce of. Adjusted it to symfony 3.
<services>
<instanceof id="Swift_Mailer">
<tag name="app.mailer"/>
</instanceof>
</services>
<service id="vop.communication.sender.communication" parent="vop.communication.sender.email.abstract" class="Vop\CommunicationBundle\Sender\CommunicationSender" autowire="true">
<!-- todo change args if using autowire-->
<argument type="service" id="vop_communication.communication_manager"/>
<argument type="service" id="sonata.notification.backend"/>
<argument key="$mailers" type="tagged" tag="app.mailer"/>
</service>
/**
* CommunicationSender constructor.
*
* @param CommunicationHistoryService $communicationHistoryService
* @param ManagerInterface $settingManager
* @param CommunicationManager $communicationManager
* @param BackendInterface $backend
*/
public function __construct(
CommunicationHistoryService $communicationHistoryService,
ManagerInterface $settingManager,
CommunicationManager $communicationManager,
BackendInterface $backend,
iterable $mailers,
KernelInterface $kernel
) {
parent::__construct($communicationHistoryService, $settingManager);
$this->communicationManager = $communicationManager;
$this->backend = $backend;
$this->mailers = $mailers;
$this->kernel = $kernel;
}
but in that case $this->mailers is empty. Why?
Update:
What I want to do is to have send($code) function which by code chooses mailer and sends email.