• Like

Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Real World Dependency Injection - IPC11 Spring Edition

  • 1,211 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,211
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
24
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Real WorldDependency Injection
  • 2. Real World Dependency Injection About me  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  enjoying PHP since 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • 3. Real World Dependency Injection What are Dependencies?
  • 4. Real World Dependency Injection What are Dependencies? Application Framework add. Libraries
  • 5. Real World Dependency Injection What are Dependencies? Controller PHP extensions Service / Model Utils Datastore(s)
  • 6. Real World Dependency Injection Are Dependencies bad?
  • 7. Real World Dependency Injection Are Dependencies bad? Dependencies are not bad!
  • 8. Real World Dependency Injection Are Dependencies bad? They are useful!
  • 9. Real World Dependency Injection Are Dependencies bad? Hard-coded dependencies are bad!
  • 10. Real World Dependency Injection Tightly coupled code
  • 11. Real World Dependency Injection No reuse of components
  • 12. Real World Dependency Injection No isolation, not testable!
  • 13. Real World Dependency Injection Development gets overcomplicated!
  • 14. Real World Dependency Injection „new“ is evil!
  • 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. Real World Dependency Injection Interfaces act as contracts
  • 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 How to Manage Dependencies?
  • 21. Real World Dependency Injection Manually resolve dependencies?
  • 22. Real World Dependency Injection Automatic wiring required! Simple Container vs. Full stacked DI Framework
  • 23. Real World Dependency Injection What is Dependency Injection?
  • 24. Real World Dependency Injection What is Dependency Injection? Consumer
  • 25. Real World Dependency Injection What is Dependency Injection? Consumer Dependencies
  • 26. Real World Dependency Injection What is Dependency Injection? Consumer Dependencies Container
  • 27. Real World Dependency Injection What is Dependency Injection? Consumer Dependencies Container
  • 28. Real World Dependency Injection How to inject a Dependency?
  • 29. Real World Dependency Injection Constructor Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  • 30. Real World Dependency Injection Setter injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function setSampleDao(ISampleDao $sampleDao){ $this->sampleDao = $sampleDao; } }
  • 31. Real World Dependency Injection Interface injection <?php interface IApplicationContextAware { public function setCtx(IApplicationContext $ctx); }
  • 32. Real World Dependency Injection Interface injection <?php class MySampleService implements IMySampleService, IApplicationContextAware { /** * @var IApplicationContext */ private $ctx; public function setCtx(IApplicationContext $ctx) { $this->ctx = $ctx; } }
  • 33. Real World Dependency Injection How to wire it all up?
  • 34. Real World Dependency Injection Annotation based wiring <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  • 35. 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; } }
  • 36. 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>
  • 37. Real World Dependency Injection External configuration - YAML services: SampleDao: class: SampleDao arguments: [app_sample, iSampleId, BoSample] SampleService: class: SampleService arguments: [@SampleDao]
  • 38. 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; } }
  • 39. Real World Dependency Injection Why Dependency Injection? DI vs. Registry vs. Service Locator
  • 40. Real World Dependency Injection Ready to unlock the door?
  • 41. Real World Dependency Injection Unittesting made easy
  • 42. 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); } }
  • 43. Real World Dependency Injection One class, multiple configurations
  • 44. Real World Dependency Injection One class, multiple configurations Page Exporter Page Exporter Released / /Published Released Published Pages Pages
  • 45. Real World Dependency Injection One class, multiple configurations Page Exporter Page Exporter Released / /Published Released Published Workingcopy Workingcopy Pages Pages Pages Pages
  • 46. Real World Dependency Injection One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
  • 47. Real World Dependency Injection One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Remember: The contract!
  • 48. 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()); } }
  • 49. Real World Dependency Injection One class, multiple configurations "Only deleted code is good code!" Oliver Gierke
  • 50. Real World Dependency Injection One class, multiple configurations <?php class PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
  • 51. 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>
  • 52. 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);
  • 53. Real World Dependency Injection One class, multiple configurations II Page Exporter Page Exporter Released / /Published Released Published Workingcopy Workingcopy Pages Pages Pages Pages
  • 54. Real World Dependency Injection One class, multiple configurations II HTML HTML Page Exporter Page Exporter Released / /Published Released Published Workingcopy Workingcopy Pages Pages Pages Pages
  • 55. Real World Dependency Injection One class, multiple configurations II HTML HTML Page Exporter Page Exporter PDF PDF Released / /Published Released Published Workingcopy Workingcopy Pages Pages Pages Pages
  • 56. Real World Dependency Injection One class, multiple configurations II <?xml version="1.0" encoding="UTF-8" ?> <beans> <bean id="ExportLive" class="PageExporter"> <constructor-arg ref="PublishedPageDao" /> <constructor-arg ref="HTMLExporter" /> </bean> <bean id="ExportWorking" class="PageExporter"> <constructor-arg ref="WorkingCopyPageDao" /> <constructor-arg ref="PDFExporter" /> </bean> </beans>
  • 57. Real World Dependency Injection One class, multiple configurations III
  • 58. Real World Dependency Injection One class, multiple configurations III http://editor.loc/page/[id]/headline/ http://editor.loc/page/[id]/content/ http://editor.loc/page/[id]/teaser/
  • 59. Real World Dependency Injection One class, multiple configurations III <?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) { } }
  • 60. Real World Dependency Injection One class, multiple configurations III <?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>
  • 61. Real World Dependency Injection Mocking external service access
  • 62. Real World Dependency Injection Mocking external service access Booking service Booking service
  • 63. Real World Dependency Injection Mocking external service access WS- WS- Booking service Booking service Connector Connector
  • 64. Real World Dependency Injection Mocking external service access WS- WS- Booking service Booking service Webservice Webservice Connector Connector
  • 65. Real World Dependency Injection Mocking external service access WS- WS- Booking service Booking service Webservice Webservice Connector Connector Remember: The contract!
  • 66. Real World Dependency Injection Mocking external service access FS- FS- Booking service Booking service Filesystem Filesystem Connector Connector
  • 67. Real World Dependency Injection Mocking external service access FS- FS- Booking service Booking service Filesystem Filesystem Connector Connector fullfills the contract!
  • 68. Real World Dependency Injection Clean, readable code
  • 69. 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()); } }
  • 70. Real World Dependency Injection No framework dependency
  • 71. 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) {} } }
  • 72. Real World Dependency Injection Benefits Loose coupling, reuse of components!
  • 73. Real World Dependency Injection Benefits Can reduce the amount of code!
  • 74. Real World Dependency Injection Benefits Helps developers to understand the code!
  • 75. 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, …
  • 76. Real World Dependency Injection Cons – Developers need mindshift Configuration ↔ Runtime
  • 77. http://joind.in/3522
  • 78. Image Creditshttp://www.sxc.hu/photo/1028452