SlideShare a Scribd company logo
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 Über mich

  Stephan Hochdörfer

  Head of IT der bitExpert AG, Mannheim

  PHP`ler seit 1999

  S.Hochdoerfer@bitExpert.de

  @shochdoerfer
Real World Dependency Injection

 Was sind Dependencies?
Real World Dependency Injection

 Was sind Dependencies?



                          Applikation




                  Framework        Bibliotheken
Real World Dependency Injection

 Was sind Dependencies?

                           Controller




  PHP Extensions         Service / Model   Utils




                          Datastore(s)
Real World Dependency Injection

 Sind Dependencies schlecht?
Real World Dependency Injection

 Sind Dependencies schlecht?




      Dependencies sind nicht schlecht!
Real World Dependency Injection

 Sind Dependencies schlecht?




                Nützlich und sinnvoll!
Real World Dependency Injection

 Sind Dependencies schlecht?




       Fixe Dependencies sind schlecht!
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 „new“ is evil!
 <?php
 class DeletePage extends Mvc_Action_AAction {
    private $pageManager;

     public function __construct() {
        $this->pageManager = new PageManager();
     }

     protected function execute(Mvc_Request $request) {
        $this->pageManager->delete(
           (int) $request->get('pageId')
        );
     }
 }
Real World Dependency Injection

 „new“ is evil!
 <?php
 class DeletePage extends Mvc_Action_AAction {
    private $pageManager;

     public function __construct(PageManager $pm) {
        $this->pageManager = $pm;
     }

     protected function execute(Mvc_Request $request) {
        $this->pageManager->delete(
           (int) $request->get('pageId')
        );
     }
 }
Real World Dependency Injection




        "High-level modules should not
         depend on low-level modules.
            Both should depend on
                 abstractions."
                        Robert C. Martin
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 „new“ is evil!
 <?php
 class DeletePage extends Mvc_Action_AAction {
    private $pageManager;

     public function __construct(IPageManager $pm) {
        $this->pageManager = $pm;
     }

     protected function execute(Mvc_Request $request) {
        $this->pageManager->delete(
           (int) $request->get('pageId')
        );
     }
 }
Real World Dependency Injection

 Wie verwaltet man Dependencies?
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 Automatismus notwendig!




     Simple Container        vs.   Full stacked
                                   DI Framework
Real World Dependency Injection

 Was ist Dependency Injection?
Real World Dependency Injection

 Was ist Dependency Injection?




   new DeletePage(new PageManager());
Real World Dependency Injection

 Was ist Dependency Injection?




    Consumer
Real World Dependency Injection

 Was ist Dependency Injection?




    Consumer            Dependencies
Real World Dependency Injection

 Was ist Dependency Injection?




    Consumer            Dependencies   Container
Real World Dependency Injection

 Was ist Dependency Injection?




    Consumer            Dependencies   Container
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 Constructor Injection
 <?php

 class MySampleService implements IMySampleService {
   /**
    * @var ISampleDao
    */
   private $sampleDao;

     public function __construct(ISampleDao $sampleDao) {
       $this->sampleDao = $sampleDao;
     }
 }
Real World Dependency Injection

 Setter Injection
 <?php

 class MySampleService implements IMySampleService {
   /**
    * @var ISampleDao
    */
   private $sampleDao;

     public function setSampleDao(ISampleDao $sampleDao){
      $this->sampleDao = $sampleDao;
     }
 }
Real World Dependency Injection

 Interface Injection
 <?php

 interface IApplicationContextAware {
   public function setCtx(IApplicationContext $ctx);
 }
Real World Dependency Injection

 Interface Injection
 <?php

 class MySampleService implements IMySampleService,
 IApplicationContextAware {
   /**
    * @var IApplicationContext
    */
   private $ctx;

     public function setCtx(IApplicationContext $ctx) {
      $this->ctx = $ctx;
     }
 }
Real World Dependency Injection

 Property Injection




              "NEIN NEIN NEIN!"
                       David Zülke
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 Annotations
 <?php

 class MySampleService implements IMySampleService {
   private $sampleDao;

     /**
      * @Inject
      */
     public function __construct(ISampleDao $sampleDao)
     {
         $this->sampleDao = $sampleDao;
     }
 }
Real World Dependency Injection

 Annotations
 <?php

 class MySampleService implements IMySampleService {
   private $sampleDao;

     /**
      * @Inject
      * @Named('TheSampleDao')
      */
     public function __construct(ISampleDao $sampleDao)
     {
         $this->sampleDao = $sampleDao;
     }
 }
Real World Dependency Injection

 Externe Konfiguration - XML

 <?xml version="1.0" encoding="UTF-8" ?>
 <beans>
    <bean id="SampleDao" class="SampleDao">
       <constructor-arg value="app_sample" />
       <constructor-arg value="iSampleId" />
       <constructor-arg value="BoSample" />
    </bean>

    <bean id="SampleService" class="MySampleService">
       <constructor-arg ref="SampleDao" />
    </bean>
 </beans>
Real World Dependency Injection

 Externe Konfiguration - YAML

 services:
   SampleDao:
     class: SampleDao
     arguments: ['app_sample', 'iSampleId', 'BoSample']
   SampleService:
     class: SampleService
     arguments: [@SampleDao]
Real World Dependency Injection

 Externe Konfiguration - PHP
 <?php
 class BeanCache extends Beanfactory_Container_PHP {
    protected function createSampleDao() {
       $oBean = new SampleDao('app_sample',
         'iSampleId', 'BoSample');
       return $oBean;
    }

     protected function createMySampleService() {
        $oBean = new MySampleService(
           $this->getBean('SampleDao')
        );
        return $oBean;
     }
 }
Real World Dependency Injection

 Interne vs. Externe Konfiguration



             Klassenkonfiguration
                     vs.
             Instanzkonfiguration
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 Unittesting einfach gemacht
Real World Dependency Injection

 Unittesting einfach gemacht
 <?php
 require_once 'PHPUnit/Framework.php';

 class ServiceTest extends PHPUnit_Framework_TestCase {
     public function testSampleService() {
       // set up dependencies
       $sampleDao = $this->getMock('ISampleDao');
       $service   = new MySampleService($sampleDao);

         // run test case
         $return = $service->doWork();

         // check assertions
         $this->assertTrue($return);
     }
 }
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung


                              Page Exporter
                               Page Exporter




      Released / /Published
       Released Published                      Workingcopy
                                               Workingcopy
             Pages
              Pages                              Pages
                                                  Pages
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung
 <?php
 abstract class PageExporter {
   protected function setPageDao(IPageDao $pageDao) {
     $this->pageDao = $pageDao;
   }
 }
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung
 <?php
 abstract class PageExporter {
   protected function setPageDao(IPageDao $pageDao) {
     $this->pageDao = $pageDao;
   }
 }


                                  Zur Erinnerung:
                                   Der Vertrag!
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung
 <?php
 class PublishedPageExporter extends PageExporter {
   public function __construct() {
     $this->setPageDao(new PublishedPageDao());
   }
 }


 class WorkingCopyPageExporter extends PageExporter {
   public function __construct() {
     $this->setPageDao(new WorkingCopyPageDao());
   }
 }
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung




     "Only deleted code is good code!"
                        Oliver Gierke
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung
 <?php
 class PageExporter {
   public function __construct(IPageDao $pageDao) {
     $this->pageDao = $pageDao;
   }
 }
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung
 <?xml version="1.0" encoding="UTF-8" ?>
 <beans>
    <bean id="ExportLive" class="PageExporter">
       <constructor-arg ref="PublishedPageDao" />
    </bean>


    <bean id="ExportWorking" class="PageExporter">
       <constructor-arg ref="WorkingCopyPageDao" />
    </bean>
 </beans>
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung
 <?php

 // create ApplicationContext instance
 $ctx = new ApplicationContext();

 // retrieve live exporter
 $exporter = $ctx->getBean('ExportLive');

 // retrieve working copy exporter
 $exporter = $ctx->getBean('ExportWorking');
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung II
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung II


       http://editor.loc/page/[id]/headline/

        http://editor.loc/page/[id]/content/

        http://editor.loc/page/[id]/teaser/
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung II
 <?php
 class EditPart extends Mvc_Action_AFormAction {
    private $pagePartsManager;
    private $type;

     public function __construct(IPagePartsManager $pm) {
        $this->pagePartsManager = $pm;
     }

     public function setType($ptype) {
        $this->type = (int) $type;
     }

     protected function process(Bo_ABo $formBackObj) {
     }
 }
Real World Dependency Injection

 Eine Klasse, mehrfache Ausprägung II
 <?xml version="1.0" encoding="UTF-8" ?>
 <beans>
    <bean id="EditHeadline" class="EditPart">
       <constructor-arg ref="PagePartDao" />
       <property name="Type" const="PType::Headline" />
    </bean>

   <bean id="EditContent" class="EditPart">
      <constructor-arg ref="PagePartDao" />
      <property name="Type" const="PType::Content" />
   </bean>

 </beans>
Real World Dependency Injection

 Externe Services mocken
Real World Dependency Injection

 Externe Services mocken




                               WS-
                                WS-
  Bookingmanager
   Bookingmanager                         Webservice
                                          Webservice
                             Konnektor
                              Konnektor
Real World Dependency Injection

 Externe Services mocken




                               WS-
                                WS-
  Bookingmanager
   Bookingmanager                         Webservice
                                          Webservice
                             Konnektor
                              Konnektor




              Zur Erinnerung:
               Der Vertrag!
Real World Dependency Injection

 Externe Services mocken




                                FS-
                                 FS-
  Bookingmanager
   Bookingmanager                         Filesystem
                                           Filesystem
                             Konnektor
                              Konnektor
Real World Dependency Injection

 Externe Services mocken




                                     FS-
                                      FS-
  Bookingmanager
   Bookingmanager                              Filesystem
                                                Filesystem
                                  Konnektor
                                   Konnektor




                    erfüllt den
                     Vertrag!
Real World Dependency Injection

 Sauberer, lesbarer Code
Real World Dependency Injection

 Sauberer, lesbarer Code
 <?php
 class DeletePage extends Mvc_Action_AAction {
    private $pageManager;

     public function __construct(IPageManager $pm) {
        $this->pageManager = $pm;
     }

     protected function execute(Mvc_Request $request) {
        $this->pageManager->delete(
           (int) $request->get('pageId'));

         return new ModelAndView($this->getSuccessView());
     }
 }
Real World Dependency Injection

 Keine Framework Abhängigkeit
Real World Dependency Injection

 Keine Framework Abhängigkeit
 <?php
 class MySampleService implements IMySampleService {
   private $sampleDao;

     public function __construct(ISampleDao $sampleDao) {
      $this->sampleDao = $sampleDao;
     }

     public function getSample($sampleId) {
      try {
        return $this->sampleDao->readById($sampleId);
      }
      catch(DaoException $exception) {}
     }
 }
Real World Dependency Injection




   Wie sieht das nun in der Praxis aus?
Real World Dependency Injection




                          Pimple
Real World Dependency Injection

 Pimple – Erste Schritte
 <?php

 class TalkService {
     public function __construct() {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 Pimple – Erste Schritte
 <?php
 require_once '/path/to/Pimple.php';
 require_once '/path/to/TalkService.php';

 // create the Container
 $container = new Pimple();

 // define talkService object in container
 $container['talkService'] = function ($c) {
     return new TalkService();
 };

 // instantiate talkService from container
 $talkService = $container['talkService'];
Real World Dependency Injection

 Pimple – Constructor Injection
 <?php

 interface GenericRepository {
     public function readTalks();
 }


 class TalkRepository implements GenericRepository {
     public function readTalks() {
     }
 }


 class TalkService {
     public function __construct(TalkRepository $repo) {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 Pimple – Constructor Injection
 <?php
 require_once '/path/to/Pimple.php';
 require_once '/path/to/TalkService.php';

 // create the Container
 $container = new Pimple();

 // define services in container
 $container['talkRepository'] = function ($c) {
     return new TalkRepository();
 };
 $container['talkService'] = function ($c) {
     return new TalkService($c['talkRepository']);
 };

 // instantiate talkService from container
 $talkService = $container['talkService'];
Real World Dependency Injection

 Pimple – Setter Injection
 <?php

 class Logger {
     public function doLog($logMsg) {
     }
 }

 class TalkService {
     public function __construct(TalkRepository $repo) {
     }

     public function setLogger(Logger $logger) {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 Pimple – Setter Injection
 <?php
 require_once '/path/to/Pimple.php';
 require_once '/path/to/TalkService.php';

 // create the Container
 $container = new Pimple();

 // define services in container
 $container['logger'] = function ($c) {
     return new Logger();
 };
 $container['talkRepository'] = function ($c) {
     return new TalkRepository();
 };
 $container['talkService'] = function ($c) {
     $service = new TalkService($c['talkRepository']);
     $service->setLogger($c['logger']);
     return $service;
 };

 // instantiate talkService from container
 $talkService = $container['talkService'];
Real World Dependency Injection

 Pimple – Allgemeines
 <?php
 require_once '/path/to/Pimple.php';
 require_once '/path/to/TalkService.php';

 // create the Container
 $container = new Pimple();

 // define services in container
 $container['loggerShared'] = $c->share(function ($c) {
     return new Logger();
 )};
 $container['logger'] = function ($c) {
     return new Logger();
 };

 // instantiate logger from container
 $logger = $container['logger'];

 // instantiate shared logger from container (same instance!)
 $logger2 = $container['loggerShared'];
 $logger3 = $container['loggerShared'];
Real World Dependency Injection




                          Bucket
Real World Dependency Injection

 Bucket – Constructor Injection
 <?php

 interface GenericRepository {
     public function readTalks();
 }


 class TalkRepository implements GenericRepository {
     public function readTalks() {
     }
 }


 class TalkService {
     public function __construct(TalkRepository $repo) {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 Bucket – Constructor Injection
 <?php
 require_once '/path/to/bucket.inc.php';
 require_once '/path/to/TalkService.php';

 // create the Container
 $container = new bucket_Container();

 // instantiate talkService from container
 $talkService = $container->create('TalkService');

 // instantiate shared instances from container
 $talkService2 = $container->get('TalkService');
 $talkService3 = $container->get('TalkService');
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 ZendDi – Erste Schritte
 <?php
 namespace Acme;

 class TalkService {
     public function __construct() {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 ZendDi – Erste Schritte
 <?php

 $di = new ZendDiDi();

 $service = $di->get('AcmeTalkService');
 $service->getTalks();
Real World Dependency Injection

 ZendDi – Constructor Injection
 <?php
 namespace Acme;

 interface GenericRepository {
     public function readTalks();
 }


 class TalkRepository implements GenericRepository {
     public function readTalks() {
     }
 }


 class TalkService {
     public function __construct(TalkRepository $repo) {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 ZendDi – Constructor Injection
 <?php

 $di = new ZendDiDi();

 $service = $di->get('AcmeTalkService');
 $service->getTalks();
Real World Dependency Injection

 ZendDi – Setter Injection
 <?php
 namespace Acme;

 class Logger {
     public function doLog($logMsg) {
     }
 }

 class TalkService {
     public function __construct(TalkRepository $repo) {
     }

     public function setLogger(Logger $logger) {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 ZendDi – Setter Injection
 <?php
 $di = new ZendDiDi();
 $di->configure(
     new ZendDiConfiguration(
          array(
              'definition' => array(
                  'class' => array(
                           'AcmeTalkService' => array(
                                    'setLogger' => array('required' => true)
                           )
                  )
              )
          )
     )
 );

 $service = $di->get('AcmeTalkService');
 var_dump($service);
Real World Dependency Injection

 ZendDi – Interface Injection
 <?php
 namespace Acme;

 class Logger {
     public function doLog($logMsg) {
     }
 }

 interface LoggerAware {
     public function setLogger(Logger $logger);
 }

 class TalkService implements LoggerAware {
     public function __construct(TalkRepository $repo) {
     }

     public function setLogger(Logger $logger) {
     }

     public function getTalks() {
     }
 }
Real World Dependency Injection

 ZendDi – Interface Injection
 <?php

 $di = new ZendDiDi();

 $service = $di->get('AcmeTalkService');
 $service->getTalks();
Real World Dependency Injection

 ZendDi – Grundsätzliches
 <?php

 $di = new ZendDiDi();

 $service = $di->get('AcmeTalkService');
 var_dump($service);


 $service2 = $di->get('AcmeTalkService');
 var_dump($service2); // same instance as $service


 $service3 = $di->get(
     'AcmeTalkService',
     array(
          'repo' => new phpbnl12TalkRepository()
     )
 );
 var_dump($service3); // new instance
Real World Dependency Injection

 ZendDi – Builder Definition
 <?php
 // describe dependency
 $dep = new ZendDiDefinitionBuilderPhpClass();
 $dep->setName('AcmeTalkRepository');

 // describe class
 $class = new ZendDiDefinitionBuilderPhpClass();
 $class->setName('AcmeTalkService');

 // add injection method
 $im = new ZendDiDefinitionBuilderInjectionMethod();
 $im->setName('__construct');
 $im->addParameter('repo', 'AcmeTalkRepository');
 $class->addInjectionMethod($im);

 // configure builder
 $builder = new ZendDiDefinitionBuilderDefinition();
 $builder->addClass($dep);
 $builder->addClass($class);
Real World Dependency Injection

 ZendDi – Builder Definition


      <?php

      // add to Di
      $defList = new ZendDiDefinitionList($builder);
      $di = new ZendDiDi($defList);

      $service = $di->get('AcmeTalkService');
      var_dump($service);
Real World Dependency Injection




    ZendServiceManager to the resuce!
Real World Dependency Injection - phpugffm13
Real World Dependency Injection

 Symfony2
 <?php
 namespace AcmeTalkBundleController;
 use SymfonyBundleFrameworkBundleControllerController;
 use SensioBundleFrameworkExtraBundleConfigurationRoute;
 use SensioBundleFrameworkExtraBundleConfigurationTemplate;

 class TalkController extends Controller {
     /**
      * @Route("/", name="_talk")
      * @Template()
      */
     public function indexAction() {
         $service = $this->get('acme.talk.service');
         return array();
     }
 }
Real World Dependency Injection

 Symfony2 – Konfigurationsdatei
 File services.xml in src/Acme/DemoBundle/Resources/config
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">


 </container>
Real World Dependency Injection

 Symfony2 – Constructor Injection
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">

     <services>
         <service id="acme.talk.repo"
              class="AcmeTalkBundleServiceTalkRepository" />

          <service id="acme.talk.service"
              class="AcmeTalkBundleServiceTalkService">
              <argument type="service" id="acme.talk.repo" />
          </service>
     </services>
 </container>
Real World Dependency Injection

 Symfony2 – Setter Injection
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">

     <services>
         <service id="acme.talk.logger"
               class="AcmeTalkBundleServiceLogger" />

         <service id="acme.talk.repo"
              class="AcmeTalkBundleServiceTalkRepository" />

          <service id="acme.talk.service"
              class="AcmeTalkBundleServiceTalkService">
              <argument type="service" id="acme.talk.repo" />
              <call method="setLogger">
                   <argument type="service" id="acme.talk.logger" />
              </call>
          </service>
     </services>
 </container>
Real World Dependency Injection

 Symfony2 – Setter Injection (optional)
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">

     <services>
         <service id="acme.talk.logger"
              class="AcmeTalkBundleServiceLogger" />

         <service id="acme.talk.repo"
             class="AcmeTalkBundleServiceTalkRepository" />

          <service id="acme.talk.service"
              class="AcmeTalkBundleServiceTalkService">
              <argument type="service" id="acme.talk.repo" />
              <call method="setLogger">
                   <argument type="service" id="acme.talk.logger"
                        on-invalid="ignore" />
              </call>
          </service>
     </services>
 </container>
Real World Dependency Injection

 Symfony2 – Property Injection
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">

     <services>
         <service id="acme.talk.repo"
              class="AcmeTalkBundleServiceTalkRepository" />

          <service id="acme.talk.service"
              class="AcmeTalkBundleServiceTalkService">
              <property name="talkRepository" type="service"
                  id="acme.talk.repo" />
          </service>
     </services>
 </container>
Real World Dependency Injection

 Symfony2 – private / öffentliche Services
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">

     <services>
         <service id="acme.talk.logger"
              class="AcmeTalkBundleServiceLogger" public="false" />

         <service id="acme.talk.repo"
             class="AcmeTalkBundleServiceTalkRepository" />

          <service id="acme.talk.service"
              class="AcmeTalkBundleServiceTalkService">
              <argument type="service" id="acme.talk.repo" />
              <call method="setLogger">
                   <argument type="service" id="acme.talk.logger" />
              </call>
          </service>
     </services>
 </container>
Real World Dependency Injection

 Symfony2 – Vererbung
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">

     <services>
         <service id="acme.talk.serviceparent"
              class="AcmeTalkBundleServiceTalkService" abstract="true">
              <property name="talkRepository" type="service"
                   id="acme.talk.repo" />
         </service>

         <service id="acme.talk.service" parent="acme.talk.serviceparent" />

          <service id="acme.talk.service2" parent="acme.talk.serviceparent" />
     </services>
 </container>
Real World Dependency Injection

 Symfony2 – Scoping
 <?xml version="1.0" ?>
 <container xmlns="http://symfony.com/schema/dic/services"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://symfony.com/schema/dic/services
 http://symfony.com/schema/dic/services/services-1.0.xsd">

     <services>
         <service id="acme.talk.repo"
              class="AcmeTalkBundleServiceTalkRepository" />

          <service id="acme.talk.service"
              class="AcmeTalkBundleServiceTalkService" scope="prototype">
              <property name="talkRepository" type="service"
                   id="acme.talk.repo" />
          </service>
     </services>
 </container>
Real World Dependency Injection
Real World Dependency Injection

 Flow3 – Constructor Injection
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkServiceInterface
      */
     protected $talkService;

     public function __construct(
         AcmeDemoServiceTalkService $talkService) {
         $this->talkService = $talkService;
     }

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Flow3 – Constructor Injection (manuell)
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkServiceInterface
      */
     protected $talkService;

     public function __construct(
         AcmeDemoServiceTalkService $talkService) {
         $this->talkService = $talkService;
     }

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Flow3 – Setter Injection (manuell)
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkServiceInterface
      */
     protected $talkService;

     public function setTalkService(
         AcmeDemoServiceTalkService $talkService) {
         $this->talkService = $talkService;
     }

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Flow3 – Setter Injection (manuell)
 File Objects.yaml in
 Packages/Application/Acme.Demo/Configuration
 # @package Acme
 AcmeDemoControllerStandardController:
   properties:
     talkService:
       object: AcmeDemoServiceTalkService
Real World Dependency Injection

 Flow3 – Setter Injection (automatisch)
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkServiceInterface
      */
     protected $talkService;

     public function injectTalkService(
         AcmeDemoServiceTalkService $talkService) {
         $this->talkService = $talkService;
     }

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Flow3 – Setter Injection (automatisch)
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkServiceInterface
      */
     protected $talkService;

     public function injectSomethingElse(
         AcmeDemoServiceTalkService $talkService) {
         $this->talkService = $talkService;
     }

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Flow3 – Property Injection
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkService
      * @FLOW3Inject
      */
     protected $talkService;

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Flow3 – Property Injection (mittels Interface)
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkServiceInterface
      * @FLOW3Inject
      */
     protected $talkService;

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Flow3 – Property Injection (mittels Interface)
 File Objects.yaml in
 Packages/Application/Acme.Demo/Configuration
 # @package Acme
 AcmeDemoServiceTalkServiceInterface:
   className: 'AcmeDemoServiceTalkService'
Real World Dependency Injection

 Flow3 – Scoping
 <?php
 namespace AcmeDemoController;

 use TYPO3FLOW3Annotations as FLOW3;

 /**
  * @FLOW3Scope("session")
  */
 class StandardController extends TYPO3FLOW3MVCControllerActionController {
     /**
      * @var AcmeDemoServiceTalkServiceInterface
      * @FLOW3Inject
      */
     protected $talkService;

     public function indexAction() {
     }
 }
Real World Dependency Injection

 Vorteile




              Lose Kopplung,
    gesteigerte Wiederverwendbarkeit !
Real World Dependency Injection

 Vorteile




           Codeumfang reduzieren,
          Fokus auf das Wesentliche!
Real World Dependency Injection

 Vorteile




          Hilft Entwicklern den Code
              besser zu verstehen!
Real World Dependency Injection

 Nachteile – Kein JSR330 für PHP


         Bucket, Crafty, FLOW3,
 Imind_Context, PicoContainer, Pimple,
    Phemto, Stubbles, Symfony 2.0,
 Sphicy, Solar, Substrate, XJConf, Yadif,
   ZendDi , Lion Framework, Spiral
   Framework, Xyster Framework, …
Real World Dependency Injection

 Nachteile – Entwickler müssen umdenken




             Konfiguration ↔ Laufzeit
Real World Dependency Injection - phpugffm13
Vielen Dank!
Image Credits
http://www.sxc.hu/photo/1028452

More Related Content

What's hot (19)

PDF
Curso Symfony - Clase 2
Javier Eguiluz
 
PDF
Zf2 how arrays will save your project
Michelangelo van Dam
 
PPTX
Zend server 6 using zf2, 2013 webinar
Yonni Mendes
 
PDF
Apigility reloaded
Ralf Eggert
 
PPS
Authentication with zend framework
George Mihailov
 
PDF
Phing for power users - frOSCon8
Stephan Hochdörfer
 
PPTX
Making Magento flying like a rocket! (A set of valuable tips for developers)
Ivan Chepurnyi
 
PDF
Instant ACLs with Zend Framework 2
Stefano Valle
 
PDF
Introduction to Zend framework
Matteo Magni
 
PDF
Boost your angular app with web workers
Enrique Oriol Bermúdez
 
PPT
2009 Hackday Taiwan Yui
JH Lee
 
ZIP
YUI 3
Dav Glass
 
PDF
Sane Async Patterns
TrevorBurnham
 
KEY
2011 a grape odyssey
Mike Hagedorn
 
PDF
Your code are my tests
Michelangelo van Dam
 
PPTX
Magento Indexes
Ivan Chepurnyi
 
PDF
Promises are so passé - Tim Perry - Codemotion Milan 2016
Codemotion
 
KEY
Design Patterns for Tablets and Smartphones
Michael Galpin
 
PPTX
Building Progressive Web Apps for Windows devices
Windows Developer
 
Curso Symfony - Clase 2
Javier Eguiluz
 
Zf2 how arrays will save your project
Michelangelo van Dam
 
Zend server 6 using zf2, 2013 webinar
Yonni Mendes
 
Apigility reloaded
Ralf Eggert
 
Authentication with zend framework
George Mihailov
 
Phing for power users - frOSCon8
Stephan Hochdörfer
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Ivan Chepurnyi
 
Instant ACLs with Zend Framework 2
Stefano Valle
 
Introduction to Zend framework
Matteo Magni
 
Boost your angular app with web workers
Enrique Oriol Bermúdez
 
2009 Hackday Taiwan Yui
JH Lee
 
YUI 3
Dav Glass
 
Sane Async Patterns
TrevorBurnham
 
2011 a grape odyssey
Mike Hagedorn
 
Your code are my tests
Michelangelo van Dam
 
Magento Indexes
Ivan Chepurnyi
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Codemotion
 
Design Patterns for Tablets and Smartphones
Michael Galpin
 
Building Progressive Web Apps for Windows devices
Windows Developer
 

Viewers also liked (6)

PDF
Dependency Injection in PHP - dwx13
Stephan Hochdörfer
 
PDF
The state of DI - DPC12
Stephan Hochdörfer
 
PDF
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Stephan Hochdörfer
 
PDF
Testing untestable code - ConFoo13
Stephan Hochdörfer
 
PDF
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Stephan Hochdörfer
 
PDF
Fließbandfertigung für Software-Applikationen
Stephan Hochdörfer
 
Dependency Injection in PHP - dwx13
Stephan Hochdörfer
 
The state of DI - DPC12
Stephan Hochdörfer
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Stephan Hochdörfer
 
Testing untestable code - ConFoo13
Stephan Hochdörfer
 
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Stephan Hochdörfer
 
Fließbandfertigung für Software-Applikationen
Stephan Hochdörfer
 
Ad

Similar to Real World Dependency Injection - phpugffm13 (20)

PDF
Real World Dependency Injection - phpday
Stephan Hochdörfer
 
PDF
Real world dependency injection - DPC10
Stephan Hochdörfer
 
KEY
Yii Introduction
Jason Ragsdale
 
PDF
WCLA12 JavaScript
Jeffrey Zinn
 
PDF
Apache Wicket Web Framework
Luther Baker
 
ODP
Dependency Injection, Zend Framework and Symfony Container
Diego Lewin
 
PDF
20150516 modern web_conf_tw
Tse-Ching Ho
 
PDF
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Java User Group Latvia
 
PPTX
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
PDF
A resource oriented framework using the DI/AOP/REST triangle
Akihito Koriyama
 
PPT
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
PDF
Multilingualism makes better programmers
Alexander Varwijk
 
PDF
Patterns Are Good For Managers
AgileThought
 
KEY
Writing your Third Plugin
Justin Ryan
 
PDF
Application Layer in PHP
Per Bernhardt
 
PDF
Doctrine For Beginners
Jonathan Wage
 
PDF
Hexagonal architecture
Alessandro Minoccheri
 
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
PDF
Introduction to DI(C)
Radek Benkel
 
PDF
Dependency Injection in Laravel
HAO-WEN ZHANG
 
Real World Dependency Injection - phpday
Stephan Hochdörfer
 
Real world dependency injection - DPC10
Stephan Hochdörfer
 
Yii Introduction
Jason Ragsdale
 
WCLA12 JavaScript
Jeffrey Zinn
 
Apache Wicket Web Framework
Luther Baker
 
Dependency Injection, Zend Framework and Symfony Container
Diego Lewin
 
20150516 modern web_conf_tw
Tse-Ching Ho
 
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Java User Group Latvia
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
A resource oriented framework using the DI/AOP/REST triangle
Akihito Koriyama
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
Multilingualism makes better programmers
Alexander Varwijk
 
Patterns Are Good For Managers
AgileThought
 
Writing your Third Plugin
Justin Ryan
 
Application Layer in PHP
Per Bernhardt
 
Doctrine For Beginners
Jonathan Wage
 
Hexagonal architecture
Alessandro Minoccheri
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
Introduction to DI(C)
Radek Benkel
 
Dependency Injection in Laravel
HAO-WEN ZHANG
 
Ad

More from Stephan Hochdörfer (20)

PDF
Offline strategies for HTML5 web applications - frOSCon8
Stephan Hochdörfer
 
PDF
Offline Strategies for HTML5 Web Applications - oscon13
Stephan Hochdörfer
 
PDF
Offline Strategien für HTML5 Web Applikationen - dwx13
Stephan Hochdörfer
 
PDF
Phing for power users - dpc_uncon13
Stephan Hochdörfer
 
PDF
Offline Strategies for HTML5 Web Applications - ipc13
Stephan Hochdörfer
 
PDF
Offline-Strategien für HTML5 Web Applikationen - wmka
Stephan Hochdörfer
 
PDF
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Stephan Hochdörfer
 
PDF
A Phing fairy tale - ConFoo13
Stephan Hochdörfer
 
PDF
Offline strategies for HTML5 web applications - ConFoo13
Stephan Hochdörfer
 
PDF
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Stephan Hochdörfer
 
PDF
Testing untestable code - IPC12
Stephan Hochdörfer
 
PDF
Offline strategies for HTML5 web applications - IPC12
Stephan Hochdörfer
 
PDF
Offline strategies for HTML5 web applications - pfCongres2012
Stephan Hochdörfer
 
PDF
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Stephan Hochdörfer
 
PDF
Testing untestable code - Herbstcampus12
Stephan Hochdörfer
 
PDF
Introducing a Software Generator Framework - JAZOON12
Stephan Hochdörfer
 
PDF
Separation of concerns - DPC12
Stephan Hochdörfer
 
PDF
Managing variability in software applications - scandev12
Stephan Hochdörfer
 
PDF
The state of DI in PHP - phpbnl12
Stephan Hochdörfer
 
PDF
Facebook für PHP Entwickler - phpugffm
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - frOSCon8
Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - oscon13
Stephan Hochdörfer
 
Offline Strategien für HTML5 Web Applikationen - dwx13
Stephan Hochdörfer
 
Phing for power users - dpc_uncon13
Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - ipc13
Stephan Hochdörfer
 
Offline-Strategien für HTML5 Web Applikationen - wmka
Stephan Hochdörfer
 
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Stephan Hochdörfer
 
A Phing fairy tale - ConFoo13
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - ConFoo13
Stephan Hochdörfer
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Stephan Hochdörfer
 
Testing untestable code - IPC12
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - IPC12
Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - pfCongres2012
Stephan Hochdörfer
 
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Stephan Hochdörfer
 
Testing untestable code - Herbstcampus12
Stephan Hochdörfer
 
Introducing a Software Generator Framework - JAZOON12
Stephan Hochdörfer
 
Separation of concerns - DPC12
Stephan Hochdörfer
 
Managing variability in software applications - scandev12
Stephan Hochdörfer
 
The state of DI in PHP - phpbnl12
Stephan Hochdörfer
 
Facebook für PHP Entwickler - phpugffm
Stephan Hochdörfer
 

Recently uploaded (20)

PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
DOCX
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 

Real World Dependency Injection - phpugffm13

  • 2. Real World Dependency Injection Über mich  Stephan Hochdörfer  Head of IT der bitExpert AG, Mannheim  PHP`ler seit 1999  [email protected]  @shochdoerfer
  • 3. Real World Dependency Injection Was sind Dependencies?
  • 4. Real World Dependency Injection Was sind Dependencies? Applikation Framework Bibliotheken
  • 5. Real World Dependency Injection Was sind Dependencies? Controller PHP Extensions Service / Model Utils Datastore(s)
  • 6. Real World Dependency Injection Sind Dependencies schlecht?
  • 7. Real World Dependency Injection Sind Dependencies schlecht? Dependencies sind nicht schlecht!
  • 8. Real World Dependency Injection Sind Dependencies schlecht? Nützlich und sinnvoll!
  • 9. Real World Dependency Injection Sind Dependencies schlecht? Fixe Dependencies sind schlecht!
  • 15. Real World Dependency Injection „new“ is evil! <?php class DeletePage extends Mvc_Action_AAction { private $pageManager; public function __construct() { $this->pageManager = new PageManager(); } protected function execute(Mvc_Request $request) { $this->pageManager->delete( (int) $request->get('pageId') ); } }
  • 16. Real World Dependency Injection „new“ is evil! <?php class DeletePage extends Mvc_Action_AAction { private $pageManager; public function __construct(PageManager $pm) { $this->pageManager = $pm; } protected function execute(Mvc_Request $request) { $this->pageManager->delete( (int) $request->get('pageId') ); } }
  • 17. Real World Dependency Injection "High-level modules should not depend on low-level modules. Both should depend on abstractions." Robert C. Martin
  • 19. Real World Dependency Injection „new“ is evil! <?php class DeletePage extends Mvc_Action_AAction { private $pageManager; public function __construct(IPageManager $pm) { $this->pageManager = $pm; } protected function execute(Mvc_Request $request) { $this->pageManager->delete( (int) $request->get('pageId') ); } }
  • 20. Real World Dependency Injection Wie verwaltet man Dependencies?
  • 22. Real World Dependency Injection Automatismus notwendig! Simple Container vs. Full stacked DI Framework
  • 23. Real World Dependency Injection Was ist Dependency Injection?
  • 24. Real World Dependency Injection Was ist Dependency Injection? new DeletePage(new PageManager());
  • 25. Real World Dependency Injection Was ist Dependency Injection? Consumer
  • 26. Real World Dependency Injection Was ist Dependency Injection? Consumer Dependencies
  • 27. Real World Dependency Injection Was ist Dependency Injection? Consumer Dependencies Container
  • 28. Real World Dependency Injection Was ist Dependency Injection? Consumer Dependencies Container
  • 30. Real World Dependency Injection Constructor Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  • 31. Real World Dependency Injection Setter Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function setSampleDao(ISampleDao $sampleDao){ $this->sampleDao = $sampleDao; } }
  • 32. Real World Dependency Injection Interface Injection <?php interface IApplicationContextAware { public function setCtx(IApplicationContext $ctx); }
  • 33. Real World Dependency Injection Interface Injection <?php class MySampleService implements IMySampleService, IApplicationContextAware { /** * @var IApplicationContext */ private $ctx; public function setCtx(IApplicationContext $ctx) { $this->ctx = $ctx; } }
  • 34. Real World Dependency Injection Property Injection "NEIN NEIN NEIN!" David Zülke
  • 36. Real World Dependency Injection Annotations <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  • 37. Real World Dependency Injection Annotations <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject * @Named('TheSampleDao') */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  • 38. Real World Dependency Injection Externe Konfiguration - XML <?xml version="1.0" encoding="UTF-8" ?> <beans> <bean id="SampleDao" class="SampleDao"> <constructor-arg value="app_sample" /> <constructor-arg value="iSampleId" /> <constructor-arg value="BoSample" /> </bean> <bean id="SampleService" class="MySampleService"> <constructor-arg ref="SampleDao" /> </bean> </beans>
  • 39. Real World Dependency Injection Externe Konfiguration - YAML services: SampleDao: class: SampleDao arguments: ['app_sample', 'iSampleId', 'BoSample'] SampleService: class: SampleService arguments: [@SampleDao]
  • 40. Real World Dependency Injection Externe Konfiguration - PHP <?php class BeanCache extends Beanfactory_Container_PHP { protected function createSampleDao() { $oBean = new SampleDao('app_sample', 'iSampleId', 'BoSample'); return $oBean; } protected function createMySampleService() { $oBean = new MySampleService( $this->getBean('SampleDao') ); return $oBean; } }
  • 41. Real World Dependency Injection Interne vs. Externe Konfiguration Klassenkonfiguration vs. Instanzkonfiguration
  • 43. Real World Dependency Injection Unittesting einfach gemacht
  • 44. Real World Dependency Injection Unittesting einfach gemacht <?php require_once 'PHPUnit/Framework.php'; class ServiceTest extends PHPUnit_Framework_TestCase { public function testSampleService() { // set up dependencies $sampleDao = $this->getMock('ISampleDao'); $service = new MySampleService($sampleDao); // run test case $return = $service->doWork(); // check assertions $this->assertTrue($return); } }
  • 45. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung
  • 46. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung Page Exporter Page Exporter Released / /Published Released Published Workingcopy Workingcopy Pages Pages Pages Pages
  • 47. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
  • 48. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Zur Erinnerung: Der Vertrag!
  • 49. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php class PublishedPageExporter extends PageExporter { public function __construct() { $this->setPageDao(new PublishedPageDao()); } } class WorkingCopyPageExporter extends PageExporter { public function __construct() { $this->setPageDao(new WorkingCopyPageDao()); } }
  • 50. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung "Only deleted code is good code!" Oliver Gierke
  • 51. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php class PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
  • 52. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?xml version="1.0" encoding="UTF-8" ?> <beans> <bean id="ExportLive" class="PageExporter"> <constructor-arg ref="PublishedPageDao" /> </bean> <bean id="ExportWorking" class="PageExporter"> <constructor-arg ref="WorkingCopyPageDao" /> </bean> </beans>
  • 53. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php // create ApplicationContext instance $ctx = new ApplicationContext(); // retrieve live exporter $exporter = $ctx->getBean('ExportLive'); // retrieve working copy exporter $exporter = $ctx->getBean('ExportWorking');
  • 54. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II
  • 55. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II http://editor.loc/page/[id]/headline/ http://editor.loc/page/[id]/content/ http://editor.loc/page/[id]/teaser/
  • 56. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II <?php class EditPart extends Mvc_Action_AFormAction { private $pagePartsManager; private $type; public function __construct(IPagePartsManager $pm) { $this->pagePartsManager = $pm; } public function setType($ptype) { $this->type = (int) $type; } protected function process(Bo_ABo $formBackObj) { } }
  • 57. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II <?xml version="1.0" encoding="UTF-8" ?> <beans> <bean id="EditHeadline" class="EditPart"> <constructor-arg ref="PagePartDao" /> <property name="Type" const="PType::Headline" /> </bean> <bean id="EditContent" class="EditPart"> <constructor-arg ref="PagePartDao" /> <property name="Type" const="PType::Content" /> </bean> </beans>
  • 58. Real World Dependency Injection Externe Services mocken
  • 59. Real World Dependency Injection Externe Services mocken WS- WS- Bookingmanager Bookingmanager Webservice Webservice Konnektor Konnektor
  • 60. Real World Dependency Injection Externe Services mocken WS- WS- Bookingmanager Bookingmanager Webservice Webservice Konnektor Konnektor Zur Erinnerung: Der Vertrag!
  • 61. Real World Dependency Injection Externe Services mocken FS- FS- Bookingmanager Bookingmanager Filesystem Filesystem Konnektor Konnektor
  • 62. Real World Dependency Injection Externe Services mocken FS- FS- Bookingmanager Bookingmanager Filesystem Filesystem Konnektor Konnektor erfüllt den Vertrag!
  • 63. Real World Dependency Injection Sauberer, lesbarer Code
  • 64. Real World Dependency Injection Sauberer, lesbarer Code <?php class DeletePage extends Mvc_Action_AAction { private $pageManager; public function __construct(IPageManager $pm) { $this->pageManager = $pm; } protected function execute(Mvc_Request $request) { $this->pageManager->delete( (int) $request->get('pageId')); return new ModelAndView($this->getSuccessView()); } }
  • 65. Real World Dependency Injection Keine Framework Abhängigkeit
  • 66. Real World Dependency Injection Keine Framework Abhängigkeit <?php class MySampleService implements IMySampleService { private $sampleDao; public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } public function getSample($sampleId) { try { return $this->sampleDao->readById($sampleId); } catch(DaoException $exception) {} } }
  • 67. Real World Dependency Injection Wie sieht das nun in der Praxis aus?
  • 68. Real World Dependency Injection Pimple
  • 69. Real World Dependency Injection Pimple – Erste Schritte <?php class TalkService { public function __construct() { } public function getTalks() { } }
  • 70. Real World Dependency Injection Pimple – Erste Schritte <?php require_once '/path/to/Pimple.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new Pimple(); // define talkService object in container $container['talkService'] = function ($c) { return new TalkService(); }; // instantiate talkService from container $talkService = $container['talkService'];
  • 71. Real World Dependency Injection Pimple – Constructor Injection <?php interface GenericRepository { public function readTalks(); } class TalkRepository implements GenericRepository { public function readTalks() { } } class TalkService { public function __construct(TalkRepository $repo) { } public function getTalks() { } }
  • 72. Real World Dependency Injection Pimple – Constructor Injection <?php require_once '/path/to/Pimple.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new Pimple(); // define services in container $container['talkRepository'] = function ($c) { return new TalkRepository(); }; $container['talkService'] = function ($c) { return new TalkService($c['talkRepository']); }; // instantiate talkService from container $talkService = $container['talkService'];
  • 73. Real World Dependency Injection Pimple – Setter Injection <?php class Logger { public function doLog($logMsg) { } } class TalkService { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  • 74. Real World Dependency Injection Pimple – Setter Injection <?php require_once '/path/to/Pimple.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new Pimple(); // define services in container $container['logger'] = function ($c) { return new Logger(); }; $container['talkRepository'] = function ($c) { return new TalkRepository(); }; $container['talkService'] = function ($c) { $service = new TalkService($c['talkRepository']); $service->setLogger($c['logger']); return $service; }; // instantiate talkService from container $talkService = $container['talkService'];
  • 75. Real World Dependency Injection Pimple – Allgemeines <?php require_once '/path/to/Pimple.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new Pimple(); // define services in container $container['loggerShared'] = $c->share(function ($c) { return new Logger(); )}; $container['logger'] = function ($c) { return new Logger(); }; // instantiate logger from container $logger = $container['logger']; // instantiate shared logger from container (same instance!) $logger2 = $container['loggerShared']; $logger3 = $container['loggerShared'];
  • 76. Real World Dependency Injection Bucket
  • 77. Real World Dependency Injection Bucket – Constructor Injection <?php interface GenericRepository { public function readTalks(); } class TalkRepository implements GenericRepository { public function readTalks() { } } class TalkService { public function __construct(TalkRepository $repo) { } public function getTalks() { } }
  • 78. Real World Dependency Injection Bucket – Constructor Injection <?php require_once '/path/to/bucket.inc.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new bucket_Container(); // instantiate talkService from container $talkService = $container->create('TalkService'); // instantiate shared instances from container $talkService2 = $container->get('TalkService'); $talkService3 = $container->get('TalkService');
  • 80. Real World Dependency Injection ZendDi – Erste Schritte <?php namespace Acme; class TalkService { public function __construct() { } public function getTalks() { } }
  • 81. Real World Dependency Injection ZendDi – Erste Schritte <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); $service->getTalks();
  • 82. Real World Dependency Injection ZendDi – Constructor Injection <?php namespace Acme; interface GenericRepository { public function readTalks(); } class TalkRepository implements GenericRepository { public function readTalks() { } } class TalkService { public function __construct(TalkRepository $repo) { } public function getTalks() { } }
  • 83. Real World Dependency Injection ZendDi – Constructor Injection <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); $service->getTalks();
  • 84. Real World Dependency Injection ZendDi – Setter Injection <?php namespace Acme; class Logger { public function doLog($logMsg) { } } class TalkService { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  • 85. Real World Dependency Injection ZendDi – Setter Injection <?php $di = new ZendDiDi(); $di->configure( new ZendDiConfiguration( array( 'definition' => array( 'class' => array( 'AcmeTalkService' => array( 'setLogger' => array('required' => true) ) ) ) ) ) ); $service = $di->get('AcmeTalkService'); var_dump($service);
  • 86. Real World Dependency Injection ZendDi – Interface Injection <?php namespace Acme; class Logger { public function doLog($logMsg) { } } interface LoggerAware { public function setLogger(Logger $logger); } class TalkService implements LoggerAware { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  • 87. Real World Dependency Injection ZendDi – Interface Injection <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); $service->getTalks();
  • 88. Real World Dependency Injection ZendDi – Grundsätzliches <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); var_dump($service); $service2 = $di->get('AcmeTalkService'); var_dump($service2); // same instance as $service $service3 = $di->get( 'AcmeTalkService', array( 'repo' => new phpbnl12TalkRepository() ) ); var_dump($service3); // new instance
  • 89. Real World Dependency Injection ZendDi – Builder Definition <?php // describe dependency $dep = new ZendDiDefinitionBuilderPhpClass(); $dep->setName('AcmeTalkRepository'); // describe class $class = new ZendDiDefinitionBuilderPhpClass(); $class->setName('AcmeTalkService'); // add injection method $im = new ZendDiDefinitionBuilderInjectionMethod(); $im->setName('__construct'); $im->addParameter('repo', 'AcmeTalkRepository'); $class->addInjectionMethod($im); // configure builder $builder = new ZendDiDefinitionBuilderDefinition(); $builder->addClass($dep); $builder->addClass($class);
  • 90. Real World Dependency Injection ZendDi – Builder Definition <?php // add to Di $defList = new ZendDiDefinitionList($builder); $di = new ZendDiDi($defList); $service = $di->get('AcmeTalkService'); var_dump($service);
  • 91. Real World Dependency Injection ZendServiceManager to the resuce!
  • 93. Real World Dependency Injection Symfony2 <?php namespace AcmeTalkBundleController; use SymfonyBundleFrameworkBundleControllerController; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; class TalkController extends Controller { /** * @Route("/", name="_talk") * @Template() */ public function indexAction() { $service = $this->get('acme.talk.service'); return array(); } }
  • 94. Real World Dependency Injection Symfony2 – Konfigurationsdatei File services.xml in src/Acme/DemoBundle/Resources/config <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> </container>
  • 95. Real World Dependency Injection Symfony2 – Constructor Injection <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <argument type="service" id="acme.talk.repo" /> </service> </services> </container>
  • 96. Real World Dependency Injection Symfony2 – Setter Injection <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.logger" class="AcmeTalkBundleServiceLogger" /> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <argument type="service" id="acme.talk.repo" /> <call method="setLogger"> <argument type="service" id="acme.talk.logger" /> </call> </service> </services> </container>
  • 97. Real World Dependency Injection Symfony2 – Setter Injection (optional) <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.logger" class="AcmeTalkBundleServiceLogger" /> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <argument type="service" id="acme.talk.repo" /> <call method="setLogger"> <argument type="service" id="acme.talk.logger" on-invalid="ignore" /> </call> </service> </services> </container>
  • 98. Real World Dependency Injection Symfony2 – Property Injection <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <property name="talkRepository" type="service" id="acme.talk.repo" /> </service> </services> </container>
  • 99. Real World Dependency Injection Symfony2 – private / öffentliche Services <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.logger" class="AcmeTalkBundleServiceLogger" public="false" /> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <argument type="service" id="acme.talk.repo" /> <call method="setLogger"> <argument type="service" id="acme.talk.logger" /> </call> </service> </services> </container>
  • 100. Real World Dependency Injection Symfony2 – Vererbung <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.serviceparent" class="AcmeTalkBundleServiceTalkService" abstract="true"> <property name="talkRepository" type="service" id="acme.talk.repo" /> </service> <service id="acme.talk.service" parent="acme.talk.serviceparent" /> <service id="acme.talk.service2" parent="acme.talk.serviceparent" /> </services> </container>
  • 101. Real World Dependency Injection Symfony2 – Scoping <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService" scope="prototype"> <property name="talkRepository" type="service" id="acme.talk.repo" /> </service> </services> </container>
  • 102. Real World Dependency Injection
  • 103. Real World Dependency Injection Flow3 – Constructor Injection <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function __construct( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 104. Real World Dependency Injection Flow3 – Constructor Injection (manuell) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function __construct( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 105. Real World Dependency Injection Flow3 – Setter Injection (manuell) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function setTalkService( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 106. Real World Dependency Injection Flow3 – Setter Injection (manuell) File Objects.yaml in Packages/Application/Acme.Demo/Configuration # @package Acme AcmeDemoControllerStandardController: properties: talkService: object: AcmeDemoServiceTalkService
  • 107. Real World Dependency Injection Flow3 – Setter Injection (automatisch) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function injectTalkService( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 108. Real World Dependency Injection Flow3 – Setter Injection (automatisch) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function injectSomethingElse( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 109. Real World Dependency Injection Flow3 – Property Injection <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkService * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  • 110. Real World Dependency Injection Flow3 – Property Injection (mittels Interface) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  • 111. Real World Dependency Injection Flow3 – Property Injection (mittels Interface) File Objects.yaml in Packages/Application/Acme.Demo/Configuration # @package Acme AcmeDemoServiceTalkServiceInterface: className: 'AcmeDemoServiceTalkService'
  • 112. Real World Dependency Injection Flow3 – Scoping <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  • 113. Real World Dependency Injection Vorteile Lose Kopplung, gesteigerte Wiederverwendbarkeit !
  • 114. Real World Dependency Injection Vorteile Codeumfang reduzieren, Fokus auf das Wesentliche!
  • 115. Real World Dependency Injection Vorteile Hilft Entwicklern den Code besser zu verstehen!
  • 116. Real World Dependency Injection Nachteile – Kein JSR330 für PHP Bucket, Crafty, FLOW3, Imind_Context, PicoContainer, Pimple, Phemto, Stubbles, Symfony 2.0, Sphicy, Solar, Substrate, XJConf, Yadif, ZendDi , Lion Framework, Spiral Framework, Xyster Framework, …
  • 117. Real World Dependency Injection Nachteile – Entwickler müssen umdenken Konfiguration ↔ Laufzeit