SlideShare a Scribd company logo
1 of 120
Download to read offline
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

 „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

 „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

 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

 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

 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

 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

 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

 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
Vielen Dank!
Image Credits
http://www.sxc.hu/photo/1028452

More Related Content

What's hot

Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2Javier Eguiluz
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your projectMichelangelo van Dam
 
Zend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarZend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarYonni Mendes
 
Apigility reloaded
Apigility reloadedApigility reloaded
Apigility reloadedRalf Eggert
 
Authentication with zend framework
Authentication with zend frameworkAuthentication with zend framework
Authentication with zend frameworkGeorge Mihailov
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8Stephan Hochdörfer
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Ivan Chepurnyi
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterHaehnchen
 
Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2Stefano Valle
 
Introduction to Zend framework
Introduction to Zend framework Introduction to Zend framework
Introduction to Zend framework Matteo Magni
 
2009 Hackday Taiwan Yui
2009 Hackday Taiwan Yui2009 Hackday Taiwan Yui
2009 Hackday Taiwan YuiJH Lee
 
2011 a grape odyssey
2011   a grape odyssey2011   a grape odyssey
2011 a grape odysseyMike Hagedorn
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Codemotion
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesMichael Galpin
 
Building Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesBuilding Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesWindows Developer
 

What's hot (20)

Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
 
Zend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarZend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinar
 
Apigility reloaded
Apigility reloadedApigility reloaded
Apigility reloaded
 
Authentication with zend framework
Authentication with zend frameworkAuthentication with zend framework
Authentication with zend framework
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
 
Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2
 
Introduction to Zend framework
Introduction to Zend framework Introduction to Zend framework
Introduction to Zend framework
 
Boost your angular app with web workers
Boost your angular app with web workersBoost your angular app with web workers
Boost your angular app with web workers
 
2009 Hackday Taiwan Yui
2009 Hackday Taiwan Yui2009 Hackday Taiwan Yui
2009 Hackday Taiwan Yui
 
YUI 3
YUI 3YUI 3
YUI 3
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
2011 a grape odyssey
2011   a grape odyssey2011   a grape odyssey
2011 a grape odyssey
 
Your code are my tests
Your code are my testsYour code are my tests
Your code are my tests
 
Magento Indexes
Magento IndexesMagento Indexes
Magento Indexes
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016
 
Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
 
Building Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesBuilding Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devices
 

Viewers also liked

Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Stephan Hochdörfer
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Stephan Hochdörfer
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Stephan Hochdörfer
 
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...Stephan Hochdörfer
 
Fließbandfertigung für Software-Applikationen
Fließbandfertigung für Software-ApplikationenFließbandfertigung für Software-Applikationen
Fließbandfertigung für Software-ApplikationenStephan Hochdörfer
 

Viewers also liked (6)

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

Similar to Real World Dependency Injection - phpugffm13

Real World Dependency Injection - phpday
Real World Dependency Injection - phpdayReal World Dependency Injection - phpday
Real World Dependency Injection - phpdayStephan Hochdörfer
 
Real world dependency injection - DPC10
Real world dependency injection - DPC10Real world dependency injection - DPC10
Real world dependency injection - DPC10Stephan Hochdörfer
 
Apache Wicket Web Framework
Apache Wicket Web FrameworkApache Wicket Web Framework
Apache Wicket Web FrameworkLuther Baker
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDiego Lewin
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_twTse-Ching Ho
 
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinMarvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinJava User Group Latvia
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
A resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangleA resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangleAkihito Koriyama
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmersAlexander Varwijk
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For ManagersAgileThought
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third PluginJustin Ryan
 
Application Layer in PHP
Application Layer in PHPApplication Layer in PHP
Application Layer in PHPPer Bernhardt
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)James Titcumb
 
Introduction to DI(C)
Introduction to DI(C)Introduction to DI(C)
Introduction to DI(C)Radek Benkel
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in LaravelHAO-WEN ZHANG
 

Similar to Real World Dependency Injection - phpugffm13 (20)

Real World Dependency Injection - phpday
Real World Dependency Injection - phpdayReal World Dependency Injection - phpday
Real World Dependency Injection - phpday
 
Real world dependency injection - DPC10
Real world dependency injection - DPC10Real world dependency injection - DPC10
Real world dependency injection - DPC10
 
Yii Introduction
Yii IntroductionYii Introduction
Yii Introduction
 
WCLA12 JavaScript
WCLA12 JavaScriptWCLA12 JavaScript
WCLA12 JavaScript
 
Apache Wicket Web Framework
Apache Wicket Web FrameworkApache Wicket Web Framework
Apache Wicket Web Framework
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
 
20150516 modern web_conf_tw
20150516 modern web_conf_tw20150516 modern web_conf_tw
20150516 modern web_conf_tw
 
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinMarvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
A resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangleA resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangle
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third Plugin
 
Application Layer in PHP
Application Layer in PHPApplication Layer in PHP
Application Layer in PHP
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Hexagonal architecture
Hexagonal architectureHexagonal architecture
Hexagonal architecture
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
Introduction to DI(C)
Introduction to DI(C)Introduction to DI(C)
Introduction to DI(C)
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
 

More from Stephan Hochdörfer

Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Stephan Hochdörfer
 
Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Stephan Hochdörfer
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Stephan Hochdörfer
 
Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaOffline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaStephan Hochdörfer
 
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Stephan Hochdörfer
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Stephan Hochdörfer
 
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12Stephan Hochdörfer
 
Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Stephan Hochdörfer
 
Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Stephan Hochdörfer
 
Managing variability in software applications - scandev12
Managing variability in software applications - scandev12Managing variability in software applications - scandev12
Managing variability in software applications - scandev12Stephan Hochdörfer
 
The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12Stephan Hochdörfer
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmStephan Hochdörfer
 

More from Stephan Hochdörfer (20)

Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13
 
Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13
 
Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaOffline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmka
 
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13
 
A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12
 
Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012Offline strategies for HTML5 web applications - pfCongres2012
Offline strategies for HTML5 web applications - pfCongres2012
 
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
 
Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12Testing untestable code - Herbstcampus12
Testing untestable code - Herbstcampus12
 
Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12Introducing a Software Generator Framework - JAZOON12
Introducing a Software Generator Framework - JAZOON12
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
Managing variability in software applications - scandev12
Managing variability in software applications - scandev12Managing variability in software applications - scandev12
Managing variability in software applications - scandev12
 
The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12The state of DI in PHP - phpbnl12
The state of DI in PHP - phpbnl12
 
Facebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffmFacebook für PHP Entwickler - phpugffm
Facebook für PHP Entwickler - phpugffm
 

Recently uploaded

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 

Real World Dependency Injection - phpugffm13

  • 1.
  • 2. 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
  • 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!
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 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
  • 18.
  • 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?
  • 21.
  • 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
  • 29.
  • 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
  • 35.
  • 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
  • 42.
  • 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');
  • 79.
  • 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!
  • 92.
  • 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
  • 118.