SlideShare a Scribd company logo
Real World
Dependency Injection
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?
What are Dependencies?
Application
Framework add. Libraries
Real World Dependency Injection
What are Dependencies?
Controller
Service / Model
Datastore(s)
UtilsPHP extensions
Real World Dependency Injection
Are Dependencies bad?
Real World Dependency Injection
Are Dependencies bad?
Dependencies are not bad!
Real World Dependency Injection
Are Dependencies 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
Real World Dependency Injection
Development gets overcomplicated!
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!
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')
);
}
}
"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
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')
);
}
}
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
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;
}
}
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
Why Dependency Injection?
Real World Dependency Injection
DI vs. Registry vs. Service Locator
Real World Dependency Injection
Ready to unlock the door?
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 ExporterPage Exporter
Released / Published
Pages
Released / Published
Pages
Real World Dependency Injection
One class, multiple configurations
Page ExporterPage Exporter
Released / Published
Pages
Released / Published
Pages
Workingcopy
Pages
Workingcopy
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
"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->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
Page ExporterPage Exporter
Released / Published
Pages
Released / Published
Pages
Workingcopy
Pages
Workingcopy
Pages
Real World Dependency Injection
One class, multiple configurations II
Page ExporterPage Exporter
Released / Published
Pages
Released / Published
Pages
Workingcopy
Pages
Workingcopy
Pages
Real World Dependency Injection
HTMLHTML
One class, multiple configurations II
Page ExporterPage Exporter
Released / Published
Pages
Released / Published
Pages
Workingcopy
Pages
Workingcopy
Pages
Real World Dependency Injection
PDFPDFHTMLHTML
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>
Real World Dependency Injection
One class, multiple configurations III
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/
Real World Dependency Injection
<?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) {
}
}
One class, multiple configurations III
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>
Real World Dependency Injection
Mocking external service access
Real World Dependency Injection
Mocking external service access
Booking serviceBooking service
Real World Dependency Injection
Mocking external service access
Booking serviceBooking service WS-
Connector
WS-
Connector
Real World Dependency Injection
Mocking external service access
Booking serviceBooking service WS-
Connector
WS-
Connector WebserviceWebservice
Real World Dependency Injection
Mocking external service access
Booking serviceBooking service WS-
Connector
WS-
Connector WebserviceWebservice
Remember:
The contract!
Real World Dependency Injection
Mocking external service access
Booking serviceBooking service FS-
Connector
FS-
Connector FilesystemFilesystem
Real World Dependency Injection
Mocking external service access
Booking serviceBooking service FS-
Connector
FS-
Connector FilesystemFilesystem
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
Real World Dependency Injection
http://joind.in/3522
Image Credits
http://www.sxc.hu/photo/1028452

More Related Content

PDF
Real World Dependency Injection - phpugffm13
PDF
Dependency Injection in PHP - dwx13
PDF
Real World Dependency Injection - oscon13
PDF
Testing untestable code - DPC10
PDF
Real World Dependency Injection SE - phpugrhh
PDF
Your Business. Your Language. Your Code - dpc13
PDF
Real World Dependency Injection - PFCongres 2010
PDF
Testing untestable Code - PFCongres 2010
Real World Dependency Injection - phpugffm13
Dependency Injection in PHP - dwx13
Real World Dependency Injection - oscon13
Testing untestable code - DPC10
Real World Dependency Injection SE - phpugrhh
Your Business. Your Language. Your Code - dpc13
Real World Dependency Injection - PFCongres 2010
Testing untestable Code - PFCongres 2010

What's hot (19)

PDF
Testing untestable code - oscon 2012
PDF
Frontin like-a-backer
PDF
QA for PHP projects
PPS
Authentication with zend framework
PDF
Curso Symfony - Clase 2
PDF
Curso Symfony - Clase 4
PPTX
Effective C++/WinRT for UWP and Win32
PDF
Dependency Injection in PHP
PDF
Apigility reloaded
PDF
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
PPTX
Building Progressive Web Apps for Windows devices
PDF
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
PDF
Workshop quality assurance for php projects - ZendCon 2013
PDF
Quick Start to iOS Development
PDF
IoC&Laravel
PDF
Your code are my tests
PDF
PHP: 4 Design Patterns to Make Better Code
PDF
UA testing with Selenium and PHPUnit - PFCongres 2013
PDF
Vue JS @ MindDoc. The progressive road to online therapy
Testing untestable code - oscon 2012
Frontin like-a-backer
QA for PHP projects
Authentication with zend framework
Curso Symfony - Clase 2
Curso Symfony - Clase 4
Effective C++/WinRT for UWP and Win32
Dependency Injection in PHP
Apigility reloaded
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
Building Progressive Web Apps for Windows devices
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
Workshop quality assurance for php projects - ZendCon 2013
Quick Start to iOS Development
IoC&Laravel
Your code are my tests
PHP: 4 Design Patterns to Make Better Code
UA testing with Selenium and PHPUnit - PFCongres 2013
Vue JS @ MindDoc. The progressive road to online therapy

Viewers also liked (8)

PDF
PHP Conference 2014: Uma string em dez milhões de documentos em menos de um s...
PDF
Mashing up JavaScript
PDF
PHP Conference 2016: Aplicações em tempo real com o Ratchet PHP
PDF
Laraconf 2016: Construindo e mantendo aplicações multi-tenant (multi-cliente)
PDF
JavaOne 2014 - Supporting Multi-tenancy Applications with Java EE
PDF
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
PDF
How to build customizable multitenant web applications - IPC11 Spring Edition
PDF
Multi-tenancy in Java
PHP Conference 2014: Uma string em dez milhões de documentos em menos de um s...
Mashing up JavaScript
PHP Conference 2016: Aplicações em tempo real com o Ratchet PHP
Laraconf 2016: Construindo e mantendo aplicações multi-tenant (multi-cliente)
JavaOne 2014 - Supporting Multi-tenancy Applications with Java EE
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
How to build customizable multitenant web applications - IPC11 Spring Edition
Multi-tenancy in Java

Similar to Real World Dependency Injection - IPC11 Spring Edition (20)

PDF
Real World Dependency Injection - phpday
PDF
Real world dependency injection - DPC10
PDF
DIC To The Limit – deSymfonyDay, Barcelona 2014
PPTX
Dependency injection with Symfony 2
PDF
What is Dependency Injection
PDF
A resource oriented framework using the DI/AOP/REST triangle
PDF
Symfony2 from the Trenches
PDF
Symfony2 - from the trenches
PDF
Dependency Inversion and Dependency Injection in PHP
ODP
Dependency Injection, Zend Framework and Symfony Container
KEY
Zend Di in ZF 2.0
PDF
14 Dependency Injection #burningkeyboards
PDF
Beyond MVC: from Model to Domain
PDF
Introduction to DI(C)
PDF
Dependency Injection
PDF
Dependency injection Drupal Camp Wrocław 2014
PPTX
The Dependency Injection - Sorin Damian, Software Developer@RomSoft
PPTX
Spring IOC and DAO
PPT
Dependency injection with PHP
PDF
Slaying Sacred Cows: Deconstructing Dependency Injection
Real World Dependency Injection - phpday
Real world dependency injection - DPC10
DIC To The Limit – deSymfonyDay, Barcelona 2014
Dependency injection with Symfony 2
What is Dependency Injection
A resource oriented framework using the DI/AOP/REST triangle
Symfony2 from the Trenches
Symfony2 - from the trenches
Dependency Inversion and Dependency Injection in PHP
Dependency Injection, Zend Framework and Symfony Container
Zend Di in ZF 2.0
14 Dependency Injection #burningkeyboards
Beyond MVC: from Model to Domain
Introduction to DI(C)
Dependency Injection
Dependency injection Drupal Camp Wrocław 2014
The Dependency Injection - Sorin Damian, Software Developer@RomSoft
Spring IOC and DAO
Dependency injection with PHP
Slaying Sacred Cows: Deconstructing Dependency Injection

More from Stephan Hochdörfer (20)

PDF
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
PDF
Phing for power users - frOSCon8
PDF
Offline strategies for HTML5 web applications - frOSCon8
PDF
Offline Strategies for HTML5 Web Applications - oscon13
PDF
Offline Strategien für HTML5 Web Applikationen - dwx13
PDF
Phing for power users - dpc_uncon13
PDF
Offline Strategies for HTML5 Web Applications - ipc13
PDF
Offline-Strategien für HTML5 Web Applikationen - wmka
PDF
Offline-Strategien für HTML5 Web Applikationen - bedcon13
PDF
Testing untestable code - ConFoo13
PDF
A Phing fairy tale - ConFoo13
PDF
Offline strategies for HTML5 web applications - ConFoo13
PDF
Offline-Strategien für HTML5Web Applikationen - WMMRN12
PDF
Testing untestable code - IPC12
PDF
Offline strategies for HTML5 web applications - IPC12
PDF
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
PDF
Offline strategies for HTML5 web applications - pfCongres2012
PDF
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
PDF
Testing untestable code - Herbstcampus12
PDF
Introducing a Software Generator Framework - JAZOON12
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Phing for power users - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategien für HTML5 Web Applikationen - dwx13
Phing for power users - dpc_uncon13
Offline Strategies for HTML5 Web Applications - ipc13
Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Testing untestable code - ConFoo13
A Phing fairy tale - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Testing untestable code - IPC12
Offline strategies for HTML5 web applications - IPC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Offline strategies for HTML5 web applications - pfCongres2012
Wie Software-Generatoren die Welt verändern können - Herbstcampus12
Testing untestable code - Herbstcampus12
Introducing a Software Generator Framework - JAZOON12

Real World Dependency Injection - IPC11 Spring Edition

  • 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. What are Dependencies? Application Framework add. Libraries Real World Dependency Injection
  • 5. What are Dependencies? Controller Service / Model Datastore(s) UtilsPHP extensions Real World Dependency Injection
  • 6. Are Dependencies bad? Real World Dependency Injection
  • 7. Are Dependencies bad? Dependencies are not bad! Real World Dependency Injection
  • 8. Are Dependencies bad? They are useful! Real World Dependency Injection
  • 9. Are Dependencies bad? Hard-coded dependencies are bad! Real World Dependency Injection
  • 10. Tightly coupled code Real World Dependency Injection
  • 11. No reuse of components Real World Dependency Injection
  • 12. No isolation, not testable! Real World Dependency Injection
  • 13. Real World Dependency Injection Development gets overcomplicated!
  • 14. Real World Dependency Injection „new“ is evil!
  • 15. <?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!
  • 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. "High-level modules should not depend on low-level modules. Both should depend on abstractions." Robert C. Martin Real World Dependency Injection
  • 18. Interfaces act as contracts Real World Dependency Injection
  • 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. How to Manage Dependencies? Real World Dependency Injection
  • 21. Manually resolve dependencies? Real World Dependency Injection
  • 22. Automatic wiring required! Simple Container vs. Full stacked DI Framework Real World Dependency Injection
  • 23. What is Dependency Injection? Real World Dependency Injection
  • 24. What is Dependency Injection? Consumer Real World Dependency Injection
  • 25. What is Dependency Injection? Consumer Dependencies Real World Dependency Injection
  • 26. What is Dependency Injection? Consumer Dependencies Container Real World Dependency Injection
  • 27. What is Dependency Injection? Consumer Dependencies Container Real World Dependency Injection
  • 28. How to inject a Dependency? 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. 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. 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
  • 37. External configuration - YAML services: SampleDao: class: SampleDao arguments: ['app_sample', 'iSampleId', 'BoSample'] SampleService: class: SampleService arguments: [@SampleDao] Real World Dependency Injection
  • 38. 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
  • 39. Why Dependency Injection? Real World Dependency Injection DI vs. Registry vs. Service Locator
  • 40. Real World Dependency Injection Ready to unlock the door?
  • 41. Unittesting made easy Real World Dependency Injection
  • 42. 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
  • 43. One class, multiple configurations Real World Dependency Injection
  • 44. One class, multiple configurations Page ExporterPage Exporter Released / Published Pages Released / Published Pages Real World Dependency Injection
  • 45. One class, multiple configurations Page ExporterPage Exporter Released / Published Pages Released / Published Pages Workingcopy Pages Workingcopy Pages Real World Dependency Injection
  • 46. One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Real World Dependency Injection
  • 47. One class, multiple configurations <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Remember: The contract! Real World Dependency Injection
  • 48. 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
  • 49. "Only deleted code is good code!" Oliver Gierke One class, multiple configurations Real World Dependency Injection
  • 50. One class, multiple configurations <?php class PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Real World Dependency Injection
  • 51. 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
  • 52. 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
  • 53. One class, multiple configurations II Page ExporterPage Exporter Released / Published Pages Released / Published Pages Workingcopy Pages Workingcopy Pages Real World Dependency Injection
  • 54. One class, multiple configurations II Page ExporterPage Exporter Released / Published Pages Released / Published Pages Workingcopy Pages Workingcopy Pages Real World Dependency Injection HTMLHTML
  • 55. One class, multiple configurations II Page ExporterPage Exporter Released / Published Pages Released / Published Pages Workingcopy Pages Workingcopy Pages Real World Dependency Injection PDFPDFHTMLHTML
  • 56. 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> Real World Dependency Injection
  • 57. One class, multiple configurations III Real World Dependency Injection
  • 58. One class, multiple configurations III http://editor.loc/page/[id]/headline/ http://editor.loc/page/[id]/content/ http://editor.loc/page/[id]/teaser/ Real World Dependency Injection
  • 59. <?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) { } } One class, multiple configurations III Real World Dependency Injection
  • 60. 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> Real World Dependency Injection
  • 61. Mocking external service access Real World Dependency Injection
  • 62. Mocking external service access Booking serviceBooking service Real World Dependency Injection
  • 63. Mocking external service access Booking serviceBooking service WS- Connector WS- Connector Real World Dependency Injection
  • 64. Mocking external service access Booking serviceBooking service WS- Connector WS- Connector WebserviceWebservice Real World Dependency Injection
  • 65. Mocking external service access Booking serviceBooking service WS- Connector WS- Connector WebserviceWebservice Remember: The contract! Real World Dependency Injection
  • 66. Mocking external service access Booking serviceBooking service FS- Connector FS- Connector FilesystemFilesystem Real World Dependency Injection
  • 67. Mocking external service access Booking serviceBooking service FS- Connector FS- Connector FilesystemFilesystem fullfills the contract! Real World Dependency Injection
  • 68. Clean, readable code Real World Dependency Injection
  • 69. 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
  • 70. No framework dependency Real World Dependency Injection
  • 71. 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
  • 72. Benefits Loose coupling, reuse of components! Real World Dependency Injection
  • 73. Benefits Can reduce the amount of code! Real World Dependency Injection
  • 74. Benefits Helps developers to understand the code! Real World Dependency Injection
  • 75. 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
  • 76. Cons – Developers need mindshift Configuration ↔ Runtime Real World Dependency Injection