class Mailer
{
private $transport;
public function __construct()
{
$this->transport = 'sendmail';
}
// ...
}
2.register this in the container as a service
use Symfony\Component\DependencyInjection\ContainerBuilder;
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('mailer', 'Mailer');
3.allow the container to set the transport used
class Mailer
{
private $transport;
public function __construct($transport)
{
$this->transport = $transport;
}
// ...
}
4.Then you can set the choice of transport in the container
use Symfony\Component\DependencyInjection\ContainerBuilder;
$containerBuilder = new ContainerBuilder();
$containerBuilder
->register('mailer', 'Mailer')
->addArgument('sendmail');
5.Which mail transport you have chosen may be something other services need to know about
use Symfony\Component\DependencyInjection\ContainerBuilder;
$containerBuilder = new ContainerBuilder();
$containerBuilder->setParameter('mailer.transport', 'sendmail');
$containerBuilder
->register('mailer', 'Mailer')
->addArgument('%mailer.transport%');
6.Now that the mailer service is in the container you can inject it as a dependency of other classes
class NewsletterManager
{
private $mailer;
public function __construct(\Mailer $mailer)
{
$this->mailer = $mailer;
}
// ...
}
7.Use the Reference class to tell the container to inject the mailer service when it initializes the newsletter manager
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$containerBuilder = new ContainerBuilder();
$containerBuilder->setParameter('mailer.transport', 'sendmail');
$containerBuilder
->register('mailer', 'Mailer')
->addArgument('%mailer.transport%');
$containerBuilder
->register('newsletter_manager', 'NewsletterManager')
->addArgument(new Reference('mailer'));
8.If the NewsletterManager did not require the Mailer and injecting it was only optional then you could use setter injection instead
class NewsletterManager
{
private $mailer;
public function setMailer(\Mailer $mailer)
{
$this->mailer = $mailer;
}
// ...
}
9. you can now choose not to inject a Mailer into the NewsletterManager. If you do want to though then the container can call the setter method
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$containerBuilder = new ContainerBuilder();
$containerBuilder->setParameter('mailer.transport', 'sendmail');
$containerBuilder
->register('mailer', 'Mailer')
->addArgument('%mailer.transport%');
$containerBuilder
->register('newsletter_manager', 'NewsletterManager')
->addMethodCall('setMailer', [new Reference('mailer')]);
10.Avoiding your Code Becoming Dependent on the Container
11.Setting up the Container with Configuration Files
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
$containerBuilder = new ContainerBuilder();
$loader = new XmlFileLoader($containerBuilder, new FileLocator(__DIR__));
$loader->load('services.xml');