Your SlideShare is downloading. ×
0
Real World
Dependency Injection
Stephan Hochdörfer, bitExpert AG
Real World Dependency Injection
About me
 Stephan Hochdörfer
 Head of IT at bitExpert AG, Germany
 enjoying PHP since 1...
Real World Dependency Injection
I so <3 Dependency Injection.
Real World Dependency Injection
Separation of Concerns
Design by Contract
Real World Dependency Injection
Real World Dependency Injection
Dependency Injection
Real World Dependency Injection
Dependency Injection
"[...] pattern that allows the removal
of hard-coded dependencies and...
Real World Dependency Injection
What are Dependencies?
Real World Dependency Injection
Are dependencies bad?
Real World Dependency Injection
Dependencies: Tight coupling
No code reuse!
Real World Dependency Injection
No isolation, not testable!
Real World Dependency Injection
Real World Dependency Injection
Dependency hell!
What is Dependency Injection?
Real World Dependency Injection
What is Dependency Injection?
Real World Dependency Injection
new DeletePage(new PageManager());
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
s
Real World Dependency Injection
„new“ is evil!
<?php
class DeletePage extends Mvc_Action_AAction {
private $pageManager;
public function __construct() {
$this->pageManag...
Real World Dependency Injection
„new“ is evil!
<?php
class DeletePage extends Mvc_Action_AAction {
private $pageManager;
p...
"High-level modules should not
depend on low-level modules.
Both should depend on abstractions."
Robert C. Martin
Real Wor...
Real World Dependency Injection
„new“ is evil!
<?php
class DeletePage extends Mvc_Action_AAction {
private $pageManager;
p...
How to manage Dependencies?
Real World Dependency Injection
How to manage Dependencies?
Simple container vs. Full stacked
DI Framework
Real World Dependency Injection
The container acts as glue point!
Real World Dependency Injection
How to inject dependencies?
Real World Dependency Injection
Constructor Injection
<?php
class MySampleService implements IMySampleService {
/**
* @var ISampleDao
*/
private $sampleDa...
Setter Injection
<?php
class MySampleService implements IMySampleService {
/**
* @var ISampleDao
*/
private $sampleDao;
pu...
Interface Injection
<?php
interface IApplicationContextAware {
public function setCtx(IApplicationContext $ctx);
}
Real Wo...
Interface Injection
<?php
class MySampleService implements IMySampleService,
IApplicationContextAware {
/**
* @var IApplic...
Property Injection
Real World Dependency Injection
Property Injection
Real World Dependency Injection
"NEIN NEIN NEIN!"
David Zülke
How to wire it all up?
Real World Dependency Injection
Real World Dependency Injection
Annotations
<?php
class MySampleService implements IMySampleService {
private $sampleDao;
...
Real World Dependency Injection
Annotations
<?php
class MySampleService implements IMySampleService {
private $sampleDao;
...
External configuration - XML
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="SampleDao" class="SampleDao">
<cons...
External configuration - YAML
services:
SampleDao:
class: SampleDao
arguments: ['app_sample', 'iSampleId', 'BoSample']
Sam...
External configuration - PHP
<?php
class BeanCache extends Beanfactory_Container_PHP {
protected function createSampleDao(...
Internal vs. external configuration
Real World Dependency Injection
Internal vs. external configuration
Real World Dependency Injection
Class configuration
vs.
Instance configuration
Real World Dependency Injection
Why use I use DI in my daily work?
Unittesting made easy
Real World Dependency Injection
Unittesting made easy
<?php
require_once 'PHPUnit/Framework.php';
class ServiceTest extends PHPUnit_Framework_TestCase {
p...
One class, multiple configurations
Real World Dependency Injection
One class, multiple configurations
Page ExporterPage Exporter
Released / Published
Pages
Released / Published
Pages
Workin...
One class, multiple configurations
<?php
abstract class PageExporter {
protected function setPageDao(IPageDao $pageDao) {
...
One class, multiple configurations
<?php
abstract class PageExporter {
protected function setPageDao(IPageDao $pageDao) {
...
One class, multiple configurations
<?php
class PublishedPageExporter extends PageExporter {
public function __construct() ...
"Only deleted code is good code!"
Oliver Gierke
One class, multiple configurations
Real World Dependency Injection
One class, multiple configurations
<?php
class PageExporter {
public function __construct(IPageDao $pageDao) {
$this->page...
One class, multiple configurations
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="ExportLive" class="PageExport...
One class, multiple configurations
<?php
// create ApplicationContext instance
$ctx = new ApplicationContext();
// retriev...
Mocking external service access
Real World Dependency Injection
Mocking external service access
Booking serviceBooking service WS-
Connector
WS-
Connector WebserviceWebservice
Real World...
Mocking external service access
Booking serviceBooking service WS-
Connector
WS-
Connector WebserviceWebservice
Real World...
Mocking external service access
Booking serviceBooking service FS-
Connector
FS-
Connector FilesystemFilesystem
Real World...
Mocking external service access
Booking serviceBooking service FS-
Connector
FS-
Connector FilesystemFilesystem
fullfills ...
Clean, readable code
Real World Dependency Injection
Clean, readable code
<?php
class DeletePage extends Mvc_Action_AAction {
private $pageManager;
public function __construct...
No framework dependencies
Real World Dependency Injection
No framework dependencies
<?php
class MySampleService implements IMySampleService {
private $sampleDao;
public function __...
Real World Dependency Injection
Getting rid of the „noise“
Real World Dependency Injection
Increase code reuse!
Real World Dependency Injection
Helps to understand the code!
Real World Dependency Injection
Brings back the fun again :)
Real World Dependency Injection
No standard. No tooling support.
Real World Dependency Injection
It takes some time to unterstand DI.
Real World Dependency Injection
Configuration vs. Runtime
Real World Dependency Injection
DI is not slow!
Thank you!
Upcoming SlideShare
Loading in...5
×

Real World Dependency Injection - oscon13

2,179

Published on

Published in: Technology, Business
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,179
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
7
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Real World Dependency Injection - oscon13"

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

    Clipping is a handy way to collect important slides you want to go back to later.

×