Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symfony Container

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Symfony Container

Avatar for Sergey Kolodyazhnyy

Sergey Kolodyazhnyy

June 09, 2015
Tweet

Other Decks in Programming

Transcript

  1. class Mage { public static function getMailer() { return new

    Mailer(); } public static function getSwiftMailer() { return new \Swift_Mailer(); } … }
  2. $swiftMailer = new \Swift_Mailer(); $mailer = new Mailer($swiftMailer); $twig =

    new \Twig_Environment(); $template = new Template\Engine($twig); $notifier = new Notifier($mailer, $template);
  3. Friendly Code • All dependencies MUST BE inside the service

    • Service SHOULD NOT be possible to instantiate without passing all compulsory dependencies • Services SHOULD NOT instantiate others services, they always have to be injected (except Builders, Factories and Service Container) • Services SHOULD NOT have circular dependencies
  4. DON’T class Notifier { public function notify($error) { // Pull

    dependencies, depends on environment $_GLOBALS[‘mailer’]—>send($error->to, $error->text); } }
  5. DO class Notifier { private $mailer; public function __construct(Mailer $mailer)

    { $this->mailer = $mailer; } public function notify($error) { // Explicit dependencies, depends on itself $this->mailer—>send($error->to, $error->text); } }
  6. DON’T class Notifier { private $mailer; // Not guaranteed that

    method will be called public function setMailer(Mailer $mailer) { $this->mailer = $mailer; } public function notify($error) { $this->mailer—>send($error->to, $error->text); } }
  7. DON’T class Notifier { … public function notify($error) { //

    Runtime is too late to know that dependency is not set if (!$this->mailer) { throw new \RuntimeException(‘Mailer is not injected :(’); } $this->mailer—>send($error->to, $error->text); } }
  8. DO class Notifier { private $mailer; // Your code won’t

    run unless you pass all dependencies public function __construct(Mailer $mailer) { $this->mailer = $mailer; } public function notify($error) { $this->mailer—>send($error->to, $error->text); } }
  9. DON’T class Notifier { private $mailer; public function __construct(\Swift_Mailer $swiftMailer)

    { // You loosing control on how Mailer instantiated // Redundant dependancy on Swift Mailer $this->mailer = new Mailer($swiftMailer); } public function notify($error) { $this->mailer—>send($error->to, $error->text); } }
  10. DON’T class Notifier { private $mailer; public function __construct(Manager $mailManager)

    { // Redundant dependancy on Mail Manager $this->mailer = $mailerManager->createMailer(); } public function notify($error) { $this->mailer—>send($error->to, $error->text); } }
  11. DO // Construct dependancy outside $mailer = new Mailer($swiftMailer); //

    Pass real dependancy instead of constructing // service inside the service $notifier = new Notifier($mailer);
  12. $container = new Pimple(); $container[‘mailer’] = function($container) { return new

    Mailer($container[‘swift_mailer’]); }; $container[‘notifier’] = function($container) { return new Notifier( $container[‘mailer’], $container[‘template’] ); }; … $container[‘notifier’]->notify(new Error());
  13. notifier: class: Error\Notifier arguments: [@mailer, @template] mailer: class: Error\Mailer arguments:

    [@swift_mailer] swift_mailer: class: \Swift_Mailer template: class: Template\Engine arguments: [@twig]