Your SlideShare is downloading. ×
  • Like
Real World Dependency Injection - oscon13
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Real World Dependency Injection - oscon13

  • 2,051 views
Published

 

Published in Technology , Business
  • 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
2,051
On SlideShare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
7
Comments
0
Likes
3

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 World Dependency Injection Stephan Hochdörfer, bitExpert AG
  • 2. Real World Dependency Injection About me  Stephan Hochdörfer  Head of IT at bitExpert AG, Germany  enjoying PHP since 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • 3. Real World Dependency Injection I so <3 Dependency Injection.
  • 4. Real World Dependency Injection Separation of Concerns
  • 5. Design by Contract Real World Dependency Injection
  • 6. Real World Dependency Injection Dependency Injection
  • 7. Real World Dependency Injection Dependency Injection "[...] pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time." (Wikipedia)
  • 8. Real World Dependency Injection What are Dependencies?
  • 9. Real World Dependency Injection Are dependencies bad?
  • 10. Real World Dependency Injection Dependencies: Tight coupling
  • 11. No code reuse! Real World Dependency Injection
  • 12. No isolation, not testable! Real World Dependency Injection
  • 13. Real World Dependency Injection Dependency hell!
  • 14. What is Dependency Injection? Real World Dependency Injection
  • 15. What is Dependency Injection? Real World Dependency Injection new DeletePage(new PageManager());
  • 16. What is Dependency Injection? Consumer Real World Dependency Injection
  • 17. What is Dependency Injection? Consumer Dependencies Real World Dependency Injection
  • 18. What is Dependency Injection? Consumer Dependencies Container Real World Dependency Injection
  • 19. What is Dependency Injection? Consumer Dependencies Container Real World Dependency Injection
  • 20. s Real World Dependency Injection „new“ is evil!
  • 21. <?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!
  • 22. 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') ); } }
  • 23. "High-level modules should not depend on low-level modules. Both should depend on abstractions." Robert C. Martin Real World Dependency Injection
  • 24. 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') ); } }
  • 25. How to manage Dependencies? Real World Dependency Injection
  • 26. How to manage Dependencies? Simple container vs. Full stacked DI Framework Real World Dependency Injection
  • 27. The container acts as glue point! Real World Dependency Injection
  • 28. How to inject dependencies? Real World Dependency Injection
  • 29. Constructor Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } } Real World Dependency Injection
  • 30. Setter Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function setSampleDao(ISampleDao $sampleDao){ $this->sampleDao = $sampleDao; } } Real World Dependency Injection
  • 31. Interface Injection <?php interface IApplicationContextAware { public function setCtx(IApplicationContext $ctx); } Real World Dependency Injection
  • 32. Interface Injection <?php class MySampleService implements IMySampleService, IApplicationContextAware { /** * @var IApplicationContext */ private $ctx; public function setCtx(IApplicationContext $ctx) { $this->ctx = $ctx; } } Real World Dependency Injection
  • 33. Property Injection Real World Dependency Injection
  • 34. Property Injection Real World Dependency Injection "NEIN NEIN NEIN!" David Zülke
  • 35. How to wire it all up? Real World Dependency Injection
  • 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. 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
  • 39. External configuration - YAML services: SampleDao: class: SampleDao arguments: ['app_sample', 'iSampleId', 'BoSample'] SampleService: class: SampleService arguments: [@SampleDao] Real World Dependency Injection
  • 40. 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
  • 41. Internal vs. external configuration Real World Dependency Injection
  • 42. Internal vs. external configuration Real World Dependency Injection Class configuration vs. Instance configuration
  • 43. Real World Dependency Injection Why use I use DI in my daily work?
  • 44. Unittesting made easy Real World Dependency Injection
  • 45. 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
  • 46. One class, multiple configurations Real World Dependency Injection
  • 47. One class, multiple configurations Page ExporterPage Exporter Released / Published Pages Released / Published Pages Workingcopy Pages Workingcopy Pages Real World Dependency Injection
  • 48. One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Real World Dependency Injection
  • 49. One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Remember: The contract! Real World Dependency Injection
  • 50. 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
  • 51. "Only deleted code is good code!" Oliver Gierke One class, multiple configurations Real World Dependency Injection
  • 52. One class, multiple configurations <?php class PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Real World Dependency Injection
  • 53. 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
  • 54. 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
  • 55. Mocking external service access Real World Dependency Injection
  • 56. Mocking external service access Booking serviceBooking service WS- Connector WS- Connector WebserviceWebservice Real World Dependency Injection
  • 57. Mocking external service access Booking serviceBooking service WS- Connector WS- Connector WebserviceWebservice Real World Dependency Injection Remember: The contract!
  • 58. Mocking external service access Booking serviceBooking service FS- Connector FS- Connector FilesystemFilesystem Real World Dependency Injection
  • 59. Mocking external service access Booking serviceBooking service FS- Connector FS- Connector FilesystemFilesystem fullfills the contact! Real World Dependency Injection
  • 60. Clean, readable code Real World Dependency Injection
  • 61. 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
  • 62. No framework dependencies Real World Dependency Injection
  • 63. No framework dependencies <?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
  • 64. Real World Dependency Injection Getting rid of the „noise“
  • 65. Real World Dependency Injection Increase code reuse!
  • 66. Real World Dependency Injection Helps to understand the code!
  • 67. Real World Dependency Injection Brings back the fun again :)
  • 68. Real World Dependency Injection No standard. No tooling support.
  • 69. Real World Dependency Injection It takes some time to unterstand DI.
  • 70. Real World Dependency Injection Configuration vs. Runtime
  • 71. Real World Dependency Injection DI is not slow!
  • 72. Thank you!