Reputation: 21236
In my application I have an SMS service. This service is a simple POPO that takes an instance to a driver to do the actual SMS functionality.
Imagine I have two drivers, mock_driver
and gateway_driver
which are defined as something like this in the services
section:
mock_driver:
class: MyApp\Service\Sms\MockDriver
gateway_driver:
class: MyApp\Service\Sms\GatewayDriver
calls:
- [setConfig, ["%gateway_user%", "%gateway_password%", "%gateway_endpoint%"]]
And the SMS service is defined like this:
service_sms:
class: MyApp\Service\SmsService
calls:
- [setDriver, ["%service_sms_driver%"]]
The problem I'm facing is that I want to pass an "instance" of one of the two drivers into the setDriver
method of my service. Which driver this is should be defined in my parameters.yml
, something such as:
service_sms_driver: ["@mock_driver"]
However, I'm stuck on the syntax to make this work correctly. I think the gist of it is correct except for the syntax on the service_sms_driver
value in my parameters.yml
and the setDriver
method call on the actual service.
Any help appreciated.
Edit: Just as a clarification, both drivers implement the same interface. However, every driver might need different ways of configuration which might not be captured in an interface. If I was simply passing class names it would work fine but I'm trying to inject instances instead. Hope this makes sense.
Upvotes: 4
Views: 5913
Reputation: 7525
Since your services construct differently, the idea of aliasing seems to be a correct idea.
To do so, just create your two driver services and your manager. (Note the usage of @driver
)
services.yml
gateway_driver:
class: Acme\FooBundle\GatewayDriver
mock_driver:
class: Acme\FooBundle\MockDriver
manager:
class: Acme\FooBundle\SmsManager
arguments: [ @driver ]
Then, you can edit this alias into your AcmeFooExtension
file
Acme/FooBundle/DependencyInjection/AcmeFooExtension.php
public function load(array $configs, ContainerBuilder $container)
{
$driver = $container->getParameter('service_sms_driver');
$container->setAlias('driver', $driver);
}
This will take the service_sms_driver
parameter and create an alias of this service.
Example of debugging:
config_dev.yml
parameters:
service_sms_driver: mock_driver
Running
$ php app/console --env=dev container:debug driver
Results in
[container] Information for service driver
This service is an alias for the service mock_driver
config_prod.yml
parameters:
service_sms_driver: gateway_driver
Running
$ php app/console --env=prod container:debug driver
Results in
[container] Information for service driver
This service is an alias for the service gateway_driver
config_test.yml
parameters:
service_sms_driver: unknown_driver
Running
$ php app/console --env=test container:debug driver
Results in
[Symfony\Component\DependencyInjection\Exception\InvalidArgumentException]
The service definition "unknown_driver" does not exist.
Upvotes: 14