• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Real World Dependency Injection - phpugffm13
 

Real World Dependency Injection - phpugffm13

on

  • 2,592 views

 

Statistics

Views

Total Views
2,592
Views on SlideShare
1,151
Embed Views
1,441

Actions

Likes
1
Downloads
4
Comments
0

4 Embeds 1,441

http://flow.typo3.org 1433
https://twitter.com 4
http://translate.googleusercontent.com 3
http://integration.flow.typo3.org 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Real World Dependency Injection - phpugffm13 Real World Dependency Injection - phpugffm13 Presentation Transcript

    • 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 Creditshttp://www.sxc.hu/photo/1028452