The state of DI - DPC12
Upcoming SlideShare
Loading in...5
×
 

The state of DI - DPC12

on

  • 1,360 views

 

Statistics

Views

Total Views
1,360
Views on SlideShare
1,222
Embed Views
138

Actions

Likes
3
Downloads
16
Comments
0

6 Embeds 138

http://flow.typo3.org 40
http://lanyrd.com 35
http://flow3.typo3.org 33
http://diysdk.local 18
http://protalk.me 8
http://diysdk.schlund.de 4

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

The state of DI - DPC12 The state of DI - DPC12 Presentation Transcript

  • The state of DI in PHP
  • The state of DI in PHP About me  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  enjoying PHP since 1999  7 years of DI experience (in PHP)  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • The state of DI in PHP What are Dependencies?
  • The state of DI in PHP Are Dependencies bad?
  • The state of DI in PHP Are Dependencies bad? Not at all!
  • The state of DI in PHP Are Dependencies bad? Hard-coded dependencies are bad!
  • The state of DI in PHP Tightly coupled code
  • The state of DI in PHP No reuse of components
  • The state of DI in PHP No isolation, not testable!
  • The state of DI in PHP Dependency madness!
  • The state of DI in PHP What`s DI about?
  • The state of DI in PHP What`s DI about? new TalkService(new TalkRepository());
  • The state of DI in PHP What`s DI about? Consumer
  • The state of DI in PHP What`s DI about? Consumer Dependencies
  • The state of DI in PHP What`s DI about? Consumer Dependencies Container
  • The state of DI in PHP What`s DI about? Consumer Dependencies Container
  • The state of DI in PHP A little bit of history...
  • The state of DI in PHP 1988 „Designing Reusable Classes“ Ralph E. Johnson & Brian Foote
  • The state of DI in PHP 1996 „The Dependency Inversion Principle“ Robert C. Martin
  • The state of DI in PHP 2004 „Inversion of Control Containers and the Dependency Injection pattern“ Martin Fowler
  • The state of DI in PHP 2005 / 2006 Garden, a lightweight DI container for PHP.
  • The state of DI in PHP 2006 First PHP5 framework with DI support
  • The state of DI in PHP 2007 International PHP Conference 2007 features 2 talks about DI.
  • The state of DI in PHP 2011 Zend Framework 2 (beta), Symfony2, Flow3, ...
  • The state of DI in PHP Choose wisely! Simple Container vs. Full stacked DI Framework
  • The state of DI in PHP Pimple
  • The state of DI in PHP Pimple – First steps <?php class TalkService { public function __construct() { } public function getTalks() { } }
  • The state of DI in PHP Pimple – First steps <?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];
  • The state of DI in PHP 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() { } }
  • The state of DI in PHP 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];
  • The state of DI in PHP 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() { } }
  • The state of DI in PHP 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];
  • The state of DI in PHP Pimple – General usage <?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];
  • The state of DI in PHP Bucket
  • The state of DI in PHP 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() { } }
  • The state of DI in PHP 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);
  • The state of DI in PHP
  • The state of DI in PHP ZendDi – First steps <?php namespace Acme; class TalkService { public function __construct() { } public function getTalks() { } }
  • The state of DI in PHP ZendDi – First steps <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService); $service->getTalks();
  • The state of DI in PHP 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() { } }
  • The state of DI in PHP ZendDi – Constructor Injection <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService); $service->getTalks();
  • The state of DI in PHP 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() { } }
  • The state of DI in PHP 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);
  • The state of DI in PHP 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() { } }
  • The state of DI in PHP ZendDi – Interface Injection <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService); $service->getTalks();
  • The state of DI in PHP ZendDi – General usage <?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
  • The state of DI in PHP 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);
  • The state of DI in PHP ZendDi – Builder Definition <?php // add to Di $defList = new ZendDiDefinitionList($builder); $di = new ZendDiDi($defList); $service = $di->get(AcmeTalkService); var_dump($service);
  • The state of DI in PHP
  • The state of DI in PHP 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(); } }
  • The state of DI in PHP Symfony2 – Configuration file 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>
  • The state of DI in PHP 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>
  • The state of DI in PHP 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>
  • The state of DI in PHP 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>
  • The state of DI in PHP 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>
  • The state of DI in PHP Symfony2 – Interface Injection Not supported!
  • The state of DI in PHP Symfony2 – private/public 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>
  • The state of DI in PHP Symfony2 – Service inheritance <?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>
  • The state of DI in PHP Symfony2 – Service 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>
  • The state of DI in PHP
  • The state of DI in PHP 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() { } }
  • The state of DI in PHP Flow3 – Setter Injection (manually) <?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() { } }
  • The state of DI in PHP Flow3 – Setter Injection (manually) File Objects.yaml in Packages/Application/Acme.Demo/Configuration # @package Acme AcmeDemoControllerStandardController: properties: talkService: object: AcmeDemoServiceTalkService
  • The state of DI in PHP Flow3 – Setter Injection (Automagic) <?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() { } }
  • The state of DI in PHP Flow3 – Setter Injection (Automagic) <?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() { } }
  • The state of DI in PHP Flow3 – Property Injection <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkService * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  • The state of DI in PHP Flow3 – Property Injection (with Interface) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  • The state of DI in PHP Flow3 – Property Injection (with Interface) File Objects.yaml in Packages/Application/Acme.Demo/Configuration # @package Acme AcmeDemoServiceTalkServiceInterface: className: AcmeDemoServiceTalkService
  • The state of DI in PHP 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 Benefits
  • Real World Dependency Injection Benefits Loose coupling, reuse of components!
  • Real World Dependency Injection Benefits Can reduce the amount of code!
  • Real World Dependency Injection Benefits Helps developers to understand the code!
  • Real World Dependency Injection Cons – Developers need mindshift Configuration ↔ Runtime
  • The state of DI in PHP Cons - PSR for DI container missing!
  • The state of DI in PHP Lack of IDE support
  • Thank you!
  • http://joind.in/6250