Real World Dependency Injection - oscon13

  • 2,004 views
Uploaded on

 

More 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,004
On Slideshare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
6
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!