• Like
  • Save
Real World Dependency Injection - phpday
Upcoming SlideShare
Loading in...5
×
 

Real World Dependency Injection - phpday

on

  • 5,888 views

 

Statistics

Views

Total Views
5,888
Views on SlideShare
4,912
Embed Views
976

Actions

Likes
7
Downloads
54
Comments
1

5 Embeds 976

http://www.symfony.es 962
http://lanyrd.com 9
http://symfony.es 2
http://www.thewebhatesme.com 2
http://webcache.googleusercontent.com 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

11 of 1

  • 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 - phpday Real World Dependency Injection - phpday Presentation Transcript

    • Real WorldDependency InjectionStephan Hochdörfer, bitExpert AG
    • Real World Dependency Injection About me  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  enjoying PHP since 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
    • Real World Dependency Injection What are Dependencies?
    • Real World Dependency Injection What are Dependencies? Application Framework add. Libraries
    • Real World Dependency Injection What are Dependencies? Controller PHP extensions Service / Model Utils Datastore(s)
    • Real World Dependency Injection Are Dependencies bad?
    • Real World Dependency Injection Are Dependencies bad? Dependencies are not bad! They are useful!
    • Real World Dependency Injection Are Dependencies bad? Hard-coded dependencies are bad!
    • Real World Dependency Injection Tightly coupled code
    • Real World Dependency Injection No reuse of components
    • Real World Dependency Injection No isolation, not testable!
    • Real World Dependency Injection Development gets overcomplicated!
    • Real World Dependency Injection s „new“ is evil!
    • 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 Interfaces act as contracts
    • 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 How to Manage Dependencies?
    • Real World Dependency Injection Manually resolve dependencies?
    • Real World Dependency Injection Automatic wiring required! Simple Container vs. Full stacked DI Framework
    • Real World Dependency Injection What is Dependency Injection?
    • Real World Dependency Injection What is Dependency Injection? Consumer
    • Real World Dependency Injection What is Dependency Injection? Consumer Dependencies
    • Real World Dependency Injection What is Dependency Injection? Consumer Dependencies Container
    • Real World Dependency Injection What is Dependency Injection? Consumer Dependencies Container
    • Real World Dependency Injection How to inject a Dependency?
    • 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 How to wire it all up?
    • Real World Dependency Injection Annotation based wiring <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
    • Real World Dependency Injection Annotation based wiring <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject * @Named(TheSampleDao) */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
    • Real World Dependency Injection External configuration - 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 External configuration - YAML services: SampleDao: class: SampleDao arguments: [app_sample, iSampleId, BoSample] SampleService: class: SampleService arguments: [@SampleDao]
    • Real World Dependency Injection External configuration - 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 Ready to unlock the door?
    • Real World Dependency Injection Unittesting made easy
    • Real World Dependency Injection Unittesting made easy <?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 One class, multiple configurations
    • Real World Dependency Injection One class, multiple configurations Page Exporter Page Exporter Released / /Published Released Published Workingcopy Workingcopy Pages Pages Pages Pages
    • Real World Dependency Injection One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
    • Real World Dependency Injection One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Remember: The contract!
    • Real World Dependency Injection One class, multiple configurations <?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 One class, multiple configurations "Only deleted code is good code!" Oliver Gierke
    • Real World Dependency Injection One class, multiple configurations <?php class PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
    • Real World Dependency Injection One class, multiple configurations <?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 One class, multiple configurations <?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 One class, multiple configurations II
    • Real World Dependency Injection One class, multiple configurations II http://editor.loc/page/[id]/headline/ http://editor.loc/page/[id]/content/ http://editor.loc/page/[id]/teaser/
    • Real World Dependency Injection One class, multiple configurations 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 One class, multiple configurations 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 Mocking external service access
    • Real World Dependency Injection Mocking external service access WS- WS- Booking service Booking service Webservice Webservice Connector Connector
    • Real World Dependency Injection Mocking external service access WS- WS- Booking service Booking service Webservice Webservice Connector Connector Remember: The contract!
    • Real World Dependency Injection Mocking external service access FS- FS- Booking service Booking service Filesystem Filesystem Connector Connector
    • Real World Dependency Injection Mocking external service access FS- FS- Booking service Booking service Filesystem Filesystem Connector Connector fullfills the contract!
    • Real World Dependency Injection Clean, readable code
    • Real World Dependency Injection Clean, readable 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 No framework dependency
    • Real World Dependency Injection No framework dependency <?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 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 – No JSR330 for PHP Bucket, Crafty, FLOW3, Imind_Context, PicoContainer, Pimple, Phemto, Stubbles, Symfony 2.0, Sphicy, Solar, Substrate, XJConf, Yadif, Zend_Di (Proposal), Lion Framework, Spiral Framework, Xyster Framework, …
    • Real World Dependency Injection Cons – Developers need mindshift Configuration ↔ Runtime
    • http://joind.in/3002
    • Image Creditshttp://www.sxc.hu/photo/1028452