SlideShare a Scribd company logo
Dependency Injection
Was, wie, warum?
Stephan Hochdörfer, bitExpert AG
Dependency Injection – Was, wie warum?
Über mich
 Stephan Hochdörfer
 Head of IT der bitExpert AG, Mannheim
 PHP`ler seit 1999
 S.Hochdoerfer@bitExpert.de
 @shochdoerfer
Dependency Injection – Was, wie warum?
DI ist nicht alles. Es geht um mehr.
Dependency Injection – Was, wie warum?
Separation of Concerns
Design by Contract
Dependency Injection – Was, wie warum?
Dependency Injection – Was, wie warum?
Dependency Injection
Dependency Injection – Was, wie warum?
Dependency Injection
"[...] zur Laufzeit die Abhängigkeiten
eines Objekts diesem von einem
anderen Objekt als Referenzen zur
Verfügung gestellt werden."
(Wikipedia)
Dependency Injection – Was, wie warum?
Was sind Dependencies?
Dependency Injection – Was, wie warum?
Sind Dependencies schlecht?
Dependency Injection – Was, wie warum?
Dependencies: Starke Kopplung
Keine Wiederverwendung!
Dependency Injection – Was, wie warum?
Keine Isolation, nicht testbar!
Dependency Injection – Was, wie warum?
Dependency Injection – Was, wie warum?
Dependency Wahnsinn!
Was ist Dependency Injection?
Dependency Injection – Was, wie warum?
Was ist Dependency Injection?
Dependency Injection – Was, wie warum?
new DeletePage(new PageManager());
Was ist Dependency Injection?
Consumer
Dependency Injection – Was, wie warum?
Was ist Dependency Injection?
Consumer Dependencies
Dependency Injection – Was, wie warum?
Was ist Dependency Injection?
Consumer Dependencies Container
Dependency Injection – Was, wie warum?
Was ist Dependency Injection?
Consumer Dependencies Container
Dependency Injection – Was, wie warum?
s
Dependency Injection – Was, wie warum?
„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')
);
}
}
Dependency Injection – Was, wie warum?
„new“ is evil!
Dependency Injection – Was, wie warum?
„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
Dependency Injection – Was, wie warum?
Dependency Injection – Was, wie warum?
„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')
);
}
}
Wie verwaltet man Dependencies?
Dependency Injection – Was, wie warum?
Wie verwaltet man Dependencies?
Simple Container vs. Full stacked
DI Framework
Dependency Injection – Was, wie warum?
Der Container nimmt uns die Arbeit ab!
Dependency Injection – Was, wie warum?
Wie Dependencies injizieren?
Dependency Injection – Was, wie warum?
Constructor Injection
<?php
class MySampleService implements IMySampleService {
/**
* @var ISampleDao
*/
private $sampleDao;
public function __construct(ISampleDao $sampleDao) {
$this->sampleDao = $sampleDao;
}
}
Dependency Injection – Was, wie warum?
Setter Injection
<?php
class MySampleService implements IMySampleService {
/**
* @var ISampleDao
*/
private $sampleDao;
public function setSampleDao(ISampleDao $sampleDao){
$this->sampleDao = $sampleDao;
}
}
Dependency Injection – Was, wie warum?
Interface Injection
<?php
interface IApplicationContextAware {
public function setCtx(IApplicationContext $ctx);
}
Dependency Injection – Was, wie warum?
Interface Injection
<?php
class MySampleService implements IMySampleService,
IApplicationContextAware {
/**
* @var IApplicationContext
*/
private $ctx;
public function setCtx(IApplicationContext $ctx) {
$this->ctx = $ctx;
}
}
Dependency Injection – Was, wie warum?
Property Injection
Dependency Injection – Was, wie warum?
Property Injection
Dependency Injection – Was, wie warum?
"NEIN NEIN NEIN!"
David Zülke
Wie funktioniert das „Wiring“?
Dependency Injection – Was, wie warum?
Dependency Injection – Was, wie warum?
Annotations
<?php
class MySampleService implements IMySampleService {
private $sampleDao;
/**
* @Inject
*/
public function __construct(ISampleDao $sampleDao)
{
$this->sampleDao = $sampleDao;
}
}
Dependency Injection – Was, wie warum?
Annotations
<?php
class MySampleService implements IMySampleService {
private $sampleDao;
/**
* @Inject
* @Named('TheSampleDao')
*/
public function __construct(ISampleDao $sampleDao)
{
$this->sampleDao = $sampleDao;
}
}
Externe Konfiguration - 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>
Dependency Injection – Was, wie warum?
Externe Konfiguration - YAML
services:
SampleDao:
class: SampleDao
arguments: ['app_sample', 'iSampleId', 'BoSample']
SampleService:
class: SampleService
arguments: [@SampleDao]
Dependency Injection – Was, wie warum?
Externe Konfiguration - 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;
}
}
Dependency Injection – Was, wie warum?
Interne vs. Externe Konfiguration
Dependency Injection – Was, wie warum?
Interne vs. Externe Konfiguration
Dependency Injection – Was, wie warum?
Klassenkonfiguration
vs.
Instanzkonfiguration
Dependency Injection – Was, wie warum?
Was bringt mir das? Beispiel bitte.
Unittesting einfach gemacht
Dependency Injection – Was, wie warum?
Unittesting einfach gemacht
<?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);
}
}
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
Page ExporterPage Exporter
Released / Published
Pages
Released / Published
Pages
Workingcopy
Pages
Workingcopy
Pages
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
<?php
abstract class PageExporter {
protected function setPageDao(IPageDao $pageDao) {
$this->pageDao = $pageDao;
}
}
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
<?php
abstract class PageExporter {
protected function setPageDao(IPageDao $pageDao) {
$this->pageDao = $pageDao;
}
}
Zur Erinnerung:
Der Vertrag!
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
<?php
class PublishedPageExporter extends PageExporter {
public function __construct() {
$this->setPageDao(new PublishedPageDao());
}
}
class WorkingCopyPageExporter extends PageExporter {
public function __construct() {
$this->setPageDao(new WorkingCopyPageDao());
}
}
Dependency Injection – Was, wie warum?
"Only deleted code is good code!"
Oliver Gierke
Eine Klasse, mehrfache Ausprägung
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
<?php
class PageExporter {
public function __construct(IPageDao $pageDao) {
$this->pageDao = $pageDao;
}
}
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
<?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>
Dependency Injection – Was, wie warum?
Eine Klasse, mehrfache Ausprägung
<?php
// create ApplicationContext instance
$ctx = new ApplicationContext();
// retrieve live exporter
$exporter = $ctx->getBean('ExportLive');
// retrieve working copy exporter
$exporter = $ctx->getBean('ExportWorking');
Dependency Injection – Was, wie warum?
Externe Services mocken
Dependency Injection – Was, wie warum?
Externe Services mocken
BookingmanagerBookingmanager WS-
Konnektor
WS-
Konnektor WebserviceWebservice
Dependency Injection – Was, wie warum?
Externe Services mocken
BookingmanagerBookingmanager WS-
Konnektor
WS-
Konnektor WebserviceWebservice
Dependency Injection – Was, wie warum?
Zur Erinnerung:
Der Vertrag!
Externe Services mocken
BookingmanagerBookingmanager FS-
Konnektor
FS-
Konnektor FilesystemFilesystem
Dependency Injection – Was, wie warum?
Externe Services mocken
BookingmanagerBookingmanager FS-
Konnektor
FS-
Konnektor FilesystemFilesystem
erfüllt den
Vertrag!
Dependency Injection – Was, wie warum?
Sauberer, lesbarer Code
Dependency Injection – Was, wie warum?
Sauberer, lesbarer 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());
}
}
Dependency Injection – Was, wie warum?
Keine Framework Abhängigkeit
Dependency Injection – Was, wie warum?
Keine Framework Abhängigkeit
<?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) {}
}
}
Dependency Injection – Was, wie warum?
Dependency Injection – Was, wie warum?
Wie siehst das nun in der Praxis aus?
Dependency Injection – Was, wie warum?
Pimple
Pimple – Erste Schritte
Dependency Injection – Was, wie warum?
<?php
class TalkService {
public function __construct() {
}
public function getTalks() {
}
}
Pimple – Erste Schritte
Dependency Injection – Was, wie warum?
<?php
require_once '/path/to/Pimple.php';
require_once '/path/to/TalkService.php';
// create the Container
$container = new Pimple();
// define talkService object in container
$container['talkService'] = function ($c) {
return new TalkService();
};
// instantiate talkService from container
$talkService = $container['talkService'];
Pimple – Constructor Injection
Dependency Injection – Was, wie warum?
<?php
interface GenericRepository {
public function readTalks();
}
class TalkRepository implements GenericRepository {
public function readTalks() {
}
}
class TalkService {
public function __construct(TalkRepository $repo) {
}
public function getTalks() {
}
}
Pimple – Constructor Injection
Dependency Injection – Was, wie warum?
<?php
require_once '/path/to/Pimple.php';
require_once '/path/to/TalkService.php';
// create the Container
$container = new Pimple();
// define services in container
$container['talkRepository'] = function ($c) {
return new TalkRepository();
};
$container['talkService'] = function ($c) {
return new TalkService($c['talkRepository']);
};
// instantiate talkService from container
$talkService = $container['talkService'];
Pimple – Setter Injection
Dependency Injection – Was, wie warum?
<?php
class Logger {
public function doLog($logMsg) {
}
}
class TalkService {
public function __construct(TalkRepository $repo) {
}
public function setLogger(Logger $logger) {
}
public function getTalks() {
}
}
Pimple – Setter Injection
Dependency Injection – Was, wie warum?
<?php
require_once '/path/to/Pimple.php';
require_once '/path/to/TalkService.php';
// create the Container
$container = new Pimple();
// define services in container
$container['logger'] = function ($c) {
return new Logger();
};
$container['talkRepository'] = function ($c) {
return new TalkRepository();
};
$container['talkService'] = function ($c) {
$service = new TalkService($c['talkRepository']);
$service->setLogger($c['logger']);
return $service;
};
// instantiate talkService from container
$talkService = $container['talkService'];
Dependency Injection – Was, wie warum?
ZendDi – Erste Schritte
Dependency Injection – Was, wie warum?
<?php
namespace Acme;
class TalkService {
public function __construct() {
}
public function getTalks() {
}
}
ZendDi – Erste Schritte
Dependency Injection – Was, wie warum?
<?php
$di = new ZendDiDi();
$service = $di->get('AcmeTalkService');
$service->getTalks();
ZendDi – Constructor Injection
Dependency Injection – Was, wie warum?
<?php
namespace Acme;
interface GenericRepository {
public function readTalks();
}
class TalkRepository implements GenericRepository {
public function readTalks() {
}
}
class TalkService {
public function __construct(TalkRepository $repo) {
}
public function getTalks() {
}
}
ZendDi – Constructor Injection
Dependency Injection – Was, wie warum?
<?php
$di = new ZendDiDi();
$service = $di->get('AcmeTalkService');
$service->getTalks();
ZendDi – Setter Injection
Dependency Injection – Was, wie warum?
<?php
namespace Acme;
class Logger {
public function doLog($logMsg) {
}
}
class TalkService {
public function __construct(TalkRepository $repo) {
}
public function setLogger(Logger $logger) {
}
public function getTalks() {
}
}
ZendDi – Setter Injection
Dependency Injection – Was, wie warum?
<?php
$di = new ZendDiDi();
$di->configure(
new ZendDiConfiguration(
array(
'definition' => array(
'class' => array(
'AcmeTalkService' => array(
'setLogger' => array('required' => true)
)
)
)
)
)
);
$service = $di->get('AcmeTalkService');
var_dump($service);
ZendDi – Interface Injection
Dependency Injection – Was, wie warum?
<?php
namespace Acme;
class Logger {
public function doLog($logMsg) {
}
}
interface LoggerAware {
public function setLogger(Logger $logger);
}
class TalkService implements LoggerAware {
public function __construct(TalkRepository $repo) {
}
public function setLogger(Logger $logger) {
}
public function getTalks() {
}
}
ZendDi – Interface Injection
Dependency Injection – Was, wie warum?
<?php
$di = new ZendDiDi();
$service = $di->get('AcmeTalkService');
$service->getTalks();
ZendDi – Grundsätzliches
Dependency Injection – Was, wie warum?
<?php
$di = new ZendDiDi();
$service = $di->get('AcmeTalkService');
var_dump($service);
$service2 = $di->get('AcmeTalkService');
var_dump($service2); // same instance as $service
$service3 = $di->get(
'AcmeTalkService',
array(
'repo' => new AcmeTalkRepository()
)
);
ZendDi – Builder Definition
Dependency Injection – Was, wie warum?
<?php
// describe dependency
$dep = new ZendDiDefinitionBuilderPhpClass();
$dep->setName('AcmeTalkRepository');
// describe class
$class = new ZendDiDefinitionBuilderPhpClass();
$class->setName('AcmeTalkService');
// add injection method
$im = new ZendDiDefinitionBuilderInjectionMethod();
$im->setName('__construct');
$im->addParameter('repo', 'AcmeTalkRepository');
$class->addInjectionMethod($im);
// configure builder
$builder = new ZendDiDefinitionBuilderDefinition();
$builder->addClass($dep);
$builder->addClass($class);
ZendDi – Builder Definition
Dependency Injection – Was, wie warum?
<?php
// add to Di
$defList = new ZendDiDefinitionList($builder);
$di = new ZendDiDi($defList);
$service = $di->get('AcmeTalkService');
var_dump($service);
Dependency Injection – Was, wie warum?
Symfony2
Dependency Injection – Was, wie warum?
<?php
namespace AcmeTalkBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;
class TalkController extends Controller {
/**
* @Route("/", name="_talk")
* @Template()
*/
public function indexAction() {
$service = $this->get('acme.talk.service');
return array();
}
}
Symfony2 – Konfigurationsdatei
Dependency Injection – Was, wie warum?
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
</container>
File services.xml in src/Acme/DemoBundle/Resources/config
Symfony2 – Constructor Injection
Dependency Injection – Was, wie warum?
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="acme.talk.repo"
class="AcmeTalkBundleServiceTalkRepository" />
<service id="acme.talk.service"
class="AcmeTalkBundleServiceTalkService">
<argument type="service" id="acme.talk.repo" />
</service>
</services>
</container>
Symfony2 – Setter Injection
Dependency Injection – Was, wie warum?
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="acme.talk.logger"
class="AcmeTalkBundleServiceLogger" />
<service id="acme.talk.repo"
class="AcmeTalkBundleServiceTalkRepository" />
<service id="acme.talk.service"
class="AcmeTalkBundleServiceTalkService">
<argument type="service" id="acme.talk.repo" />
<call method="setLogger">
<argument type="service" id="acme.talk.logger" />
</call>
</service>
</services>
</container>
Symfony2 – Setter Injection (optional)
Dependency Injection – Was, wie warum?
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="acme.talk.logger"
class="AcmeTalkBundleServiceLogger" />
<service id="acme.talk.repo"
class="AcmeTalkBundleServiceTalkRepository" />
<service id="acme.talk.service"
class="AcmeTalkBundleServiceTalkService">
<argument type="service" id="acme.talk.repo" />
<call method="setLogger">
<argument type="service" id="acme.talk.logger"
on-invalid="ignore" />
</call>
</service>
</services>
</container>
Symfony2 – Property Injection
Dependency Injection – Was, wie warum?
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="acme.talk.repo"
class="AcmeTalkBundleServiceTalkRepository" />
<service id="acme.talk.service"
class="AcmeTalkBundleServiceTalkService">
<property name="talkRepository" type="service"
id="acme.talk.repo" />
</service>
</services>
</container>
Dependency Injection – Was, wie warum?
Flow3 – Constructor Injection
Dependency Injection – Was, wie warum?
<?php
namespace AcmeDemoController;
use TYPO3FLOW3Annotations as FLOW3;
/**
* @FLOW3Scope("session")
*/
class StandardController extends TYPO3FLOW3MVCControllerActionController {
/**
* @var AcmeDemoServiceTalkServiceInterface
*/
protected $talkService;
public function __construct(
AcmeDemoServiceTalkService $talkService) {
$this->talkService = $talkService;
}
public function indexAction() {
}
}
Flow3 – Setter Injection (manuell)
Dependency Injection – Was, wie warum?
<?php
namespace AcmeDemoController;
use TYPO3FLOW3Annotations as FLOW3;
/**
* @FLOW3Scope("session")
*/
class StandardController extends TYPO3FLOW3MVCControllerActionController {
/**
* @var AcmeDemoServiceTalkServiceInterface
*/
protected $talkService;
public function setTalkService(
AcmeDemoServiceTalkService $talkService) {
$this->talkService = $talkService;
}
public function indexAction() {
}
}
Flow3 – Setter Injection (manuell)
Dependency Injection – Was, wie warum?
File Objects.yaml in Packages/Application/Acme.Demo/Configuration
# @package Acme
AcmeDemoControllerStandardController:
properties:
talkService:
object: AcmeDemoServiceTalkService
Flow3 – Setter Injection (automatisch)
Dependency Injection – Was, wie warum?
<?php
namespace AcmeDemoController;
use TYPO3FLOW3Annotations as FLOW3;
/**
* @FLOW3Scope("session")
*/
class StandardController extends TYPO3FLOW3MVCControllerActionController {
/**
* @var AcmeDemoServiceTalkServiceInterface
*/
protected $talkService;
public function injectTalkService(
AcmeDemoServiceTalkService $talkService) {
$this->talkService = $talkService;
}
public function indexAction() {
}
}
Dependency Injection – Was, wie warum?
Fokus aufs Wesentliche. Keine Ablenkung.
Dependency Injection – Was, wie warum?
Wiederverwendung steigern.
Dependency Injection – Was, wie warum?
Hilft den Code besser zu verstehen.
Dependency Injection – Was, wie warum?
Wieder Spaß bei der Arbeit ;)
Dependency Injection – Was, wie warum?
Kein Standard. Kein Tooling.
Dependency Injection – Was, wie warum?
Es braucht Zeit um DI zu verstehen.
Dependency Injection – Was, wie warum?
Konfiguration vs. Laufzeit
Vielen Dank!

More Related Content

What's hot (19)

PDF
Curso Symfony - Clase 4
Javier Eguiluz
 
PDF
Curso Symfony - Clase 2
Javier Eguiluz
 
PDF
Zf2 how arrays will save your project
Michelangelo van Dam
 
PPTX
Zend server 6 using zf2, 2013 webinar
Yonni Mendes
 
PPS
Authentication with zend framework
George Mihailov
 
PDF
Phing for power users - frOSCon8
Stephan Hochdörfer
 
PPTX
Making Magento flying like a rocket! (A set of valuable tips for developers)
Ivan Chepurnyi
 
PDF
Instant ACLs with Zend Framework 2
Stefano Valle
 
PDF
Quick Start to iOS Development
Jussi Pohjolainen
 
PDF
Boost your angular app with web workers
Enrique Oriol Bermúdez
 
PDF
Introduction to Zend framework
Matteo Magni
 
KEY
2011 a grape odyssey
Mike Hagedorn
 
PDF
Sane Async Patterns
TrevorBurnham
 
ZIP
YUI 3
Dav Glass
 
PDF
Your code are my tests
Michelangelo van Dam
 
KEY
Design Patterns for Tablets and Smartphones
Michael Galpin
 
PPTX
Magento Indexes
Ivan Chepurnyi
 
PDF
Promises are so passé - Tim Perry - Codemotion Milan 2016
Codemotion
 
PPTX
Building Progressive Web Apps for Windows devices
Windows Developer
 
Curso Symfony - Clase 4
Javier Eguiluz
 
Curso Symfony - Clase 2
Javier Eguiluz
 
Zf2 how arrays will save your project
Michelangelo van Dam
 
Zend server 6 using zf2, 2013 webinar
Yonni Mendes
 
Authentication with zend framework
George Mihailov
 
Phing for power users - frOSCon8
Stephan Hochdörfer
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Ivan Chepurnyi
 
Instant ACLs with Zend Framework 2
Stefano Valle
 
Quick Start to iOS Development
Jussi Pohjolainen
 
Boost your angular app with web workers
Enrique Oriol Bermúdez
 
Introduction to Zend framework
Matteo Magni
 
2011 a grape odyssey
Mike Hagedorn
 
Sane Async Patterns
TrevorBurnham
 
YUI 3
Dav Glass
 
Your code are my tests
Michelangelo van Dam
 
Design Patterns for Tablets and Smartphones
Michael Galpin
 
Magento Indexes
Ivan Chepurnyi
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Codemotion
 
Building Progressive Web Apps for Windows devices
Windows Developer
 

Similar to Dependency Injection in PHP - dwx13 (20)

PDF
Real World Dependency Injection - phpugffm13
Stephan Hochdörfer
 
PDF
Real World Dependency Injection - phpday
Stephan Hochdörfer
 
PDF
Real world dependency injection - DPC10
Stephan Hochdörfer
 
PDF
Dependency Injection in Laravel
HAO-WEN ZHANG
 
ODP
Dependency Injection, Zend Framework and Symfony Container
Diego Lewin
 
PDF
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
PDF
20150516 modern web_conf_tw
Tse-Ching Ho
 
PDF
Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Richard McIntyre
 
KEY
Yii Introduction
Jason Ragsdale
 
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
James Titcumb
 
PDF
From 0 to Spring Security 4.0
robwinch
 
ODP
Angular js-crash-course
Keith Bloomfield
 
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
PDF
Čtvrtkon #53 - Štěpán Zikmund
Péhápkaři
 
PDF
WCLA12 JavaScript
Jeffrey Zinn
 
PPTX
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
PDF
深入淺出 MVC
Jace Ju
 
PDF
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
James Titcumb
 
Real World Dependency Injection - phpugffm13
Stephan Hochdörfer
 
Real World Dependency Injection - phpday
Stephan Hochdörfer
 
Real world dependency injection - DPC10
Stephan Hochdörfer
 
Dependency Injection in Laravel
HAO-WEN ZHANG
 
Dependency Injection, Zend Framework and Symfony Container
Diego Lewin
 
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
20150516 modern web_conf_tw
Tse-Ching Ho
 
Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Richard McIntyre
 
Yii Introduction
Jason Ragsdale
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
James Titcumb
 
From 0 to Spring Security 4.0
robwinch
 
Angular js-crash-course
Keith Bloomfield
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
Čtvrtkon #53 - Štěpán Zikmund
Péhápkaři
 
WCLA12 JavaScript
Jeffrey Zinn
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
arcware
 
深入淺出 MVC
Jace Ju
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
James Titcumb
 
Ad

More from Stephan Hochdörfer (20)

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

Recently uploaded (20)

PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
PDF
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
PDF
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
"AI Transformation: Directions and Challenges", Pavlo Shaternik
Fwdays
 
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 

Dependency Injection in PHP - dwx13

  • 1. Dependency Injection Was, wie, warum? Stephan Hochdörfer, bitExpert AG
  • 2. Dependency Injection – Was, wie warum? Über mich  Stephan Hochdörfer  Head of IT der bitExpert AG, Mannheim  PHP`ler seit 1999  [email protected]  @shochdoerfer
  • 3. Dependency Injection – Was, wie warum? DI ist nicht alles. Es geht um mehr.
  • 4. Dependency Injection – Was, wie warum? Separation of Concerns
  • 5. Design by Contract Dependency Injection – Was, wie warum?
  • 6. Dependency Injection – Was, wie warum? Dependency Injection
  • 7. Dependency Injection – Was, wie warum? Dependency Injection "[...] zur Laufzeit die Abhängigkeiten eines Objekts diesem von einem anderen Objekt als Referenzen zur Verfügung gestellt werden." (Wikipedia)
  • 8. Dependency Injection – Was, wie warum? Was sind Dependencies?
  • 9. Dependency Injection – Was, wie warum? Sind Dependencies schlecht?
  • 10. Dependency Injection – Was, wie warum? Dependencies: Starke Kopplung
  • 12. Keine Isolation, nicht testbar! Dependency Injection – Was, wie warum?
  • 13. Dependency Injection – Was, wie warum? Dependency Wahnsinn!
  • 14. Was ist Dependency Injection? Dependency Injection – Was, wie warum?
  • 15. Was ist Dependency Injection? Dependency Injection – Was, wie warum? new DeletePage(new PageManager());
  • 16. Was ist Dependency Injection? Consumer Dependency Injection – Was, wie warum?
  • 17. Was ist Dependency Injection? Consumer Dependencies Dependency Injection – Was, wie warum?
  • 18. Was ist Dependency Injection? Consumer Dependencies Container Dependency Injection – Was, wie warum?
  • 19. Was ist Dependency Injection? Consumer Dependencies Container Dependency Injection – Was, wie warum?
  • 20. s Dependency Injection – Was, wie warum? „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') ); } } Dependency Injection – Was, wie warum? „new“ is evil!
  • 22. Dependency Injection – Was, wie warum? „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 Dependency Injection – Was, wie warum?
  • 24. Dependency Injection – Was, wie warum? „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. Wie verwaltet man Dependencies? Dependency Injection – Was, wie warum?
  • 26. Wie verwaltet man Dependencies? Simple Container vs. Full stacked DI Framework Dependency Injection – Was, wie warum?
  • 27. Der Container nimmt uns die Arbeit ab! Dependency Injection – Was, wie warum?
  • 28. Wie Dependencies injizieren? Dependency Injection – Was, wie warum?
  • 29. Constructor Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } } Dependency Injection – Was, wie warum?
  • 30. Setter Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function setSampleDao(ISampleDao $sampleDao){ $this->sampleDao = $sampleDao; } } Dependency Injection – Was, wie warum?
  • 31. Interface Injection <?php interface IApplicationContextAware { public function setCtx(IApplicationContext $ctx); } Dependency Injection – Was, wie warum?
  • 32. Interface Injection <?php class MySampleService implements IMySampleService, IApplicationContextAware { /** * @var IApplicationContext */ private $ctx; public function setCtx(IApplicationContext $ctx) { $this->ctx = $ctx; } } Dependency Injection – Was, wie warum?
  • 34. Property Injection Dependency Injection – Was, wie warum? "NEIN NEIN NEIN!" David Zülke
  • 35. Wie funktioniert das „Wiring“? Dependency Injection – Was, wie warum?
  • 36. Dependency Injection – Was, wie warum? Annotations <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  • 37. Dependency Injection – Was, wie warum? Annotations <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject * @Named('TheSampleDao') */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  • 38. Externe Konfiguration - 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> Dependency Injection – Was, wie warum?
  • 39. Externe Konfiguration - YAML services: SampleDao: class: SampleDao arguments: ['app_sample', 'iSampleId', 'BoSample'] SampleService: class: SampleService arguments: [@SampleDao] Dependency Injection – Was, wie warum?
  • 40. Externe Konfiguration - 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; } } Dependency Injection – Was, wie warum?
  • 41. Interne vs. Externe Konfiguration Dependency Injection – Was, wie warum?
  • 42. Interne vs. Externe Konfiguration Dependency Injection – Was, wie warum? Klassenkonfiguration vs. Instanzkonfiguration
  • 43. Dependency Injection – Was, wie warum? Was bringt mir das? Beispiel bitte.
  • 44. Unittesting einfach gemacht Dependency Injection – Was, wie warum?
  • 45. Unittesting einfach gemacht <?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); } } Dependency Injection – Was, wie warum?
  • 46. Eine Klasse, mehrfache Ausprägung Dependency Injection – Was, wie warum?
  • 47. Eine Klasse, mehrfache Ausprägung Page ExporterPage Exporter Released / Published Pages Released / Published Pages Workingcopy Pages Workingcopy Pages Dependency Injection – Was, wie warum?
  • 48. Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Dependency Injection – Was, wie warum?
  • 49. Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Zur Erinnerung: Der Vertrag! Dependency Injection – Was, wie warum?
  • 50. Eine Klasse, mehrfache Ausprägung <?php class PublishedPageExporter extends PageExporter { public function __construct() { $this->setPageDao(new PublishedPageDao()); } } class WorkingCopyPageExporter extends PageExporter { public function __construct() { $this->setPageDao(new WorkingCopyPageDao()); } } Dependency Injection – Was, wie warum?
  • 51. "Only deleted code is good code!" Oliver Gierke Eine Klasse, mehrfache Ausprägung Dependency Injection – Was, wie warum?
  • 52. Eine Klasse, mehrfache Ausprägung <?php class PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Dependency Injection – Was, wie warum?
  • 53. Eine Klasse, mehrfache Ausprägung <?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> Dependency Injection – Was, wie warum?
  • 54. Eine Klasse, mehrfache Ausprägung <?php // create ApplicationContext instance $ctx = new ApplicationContext(); // retrieve live exporter $exporter = $ctx->getBean('ExportLive'); // retrieve working copy exporter $exporter = $ctx->getBean('ExportWorking'); Dependency Injection – Was, wie warum?
  • 55. Externe Services mocken Dependency Injection – Was, wie warum?
  • 56. Externe Services mocken BookingmanagerBookingmanager WS- Konnektor WS- Konnektor WebserviceWebservice Dependency Injection – Was, wie warum?
  • 57. Externe Services mocken BookingmanagerBookingmanager WS- Konnektor WS- Konnektor WebserviceWebservice Dependency Injection – Was, wie warum? Zur Erinnerung: Der Vertrag!
  • 58. Externe Services mocken BookingmanagerBookingmanager FS- Konnektor FS- Konnektor FilesystemFilesystem Dependency Injection – Was, wie warum?
  • 59. Externe Services mocken BookingmanagerBookingmanager FS- Konnektor FS- Konnektor FilesystemFilesystem erfüllt den Vertrag! Dependency Injection – Was, wie warum?
  • 60. Sauberer, lesbarer Code Dependency Injection – Was, wie warum?
  • 61. Sauberer, lesbarer 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()); } } Dependency Injection – Was, wie warum?
  • 62. Keine Framework Abhängigkeit Dependency Injection – Was, wie warum?
  • 63. Keine Framework Abhängigkeit <?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) {} } } Dependency Injection – Was, wie warum?
  • 64. Dependency Injection – Was, wie warum? Wie siehst das nun in der Praxis aus?
  • 65. Dependency Injection – Was, wie warum? Pimple
  • 66. Pimple – Erste Schritte Dependency Injection – Was, wie warum? <?php class TalkService { public function __construct() { } public function getTalks() { } }
  • 67. Pimple – Erste Schritte Dependency Injection – Was, wie warum? <?php require_once '/path/to/Pimple.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new Pimple(); // define talkService object in container $container['talkService'] = function ($c) { return new TalkService(); }; // instantiate talkService from container $talkService = $container['talkService'];
  • 68. Pimple – Constructor Injection Dependency Injection – Was, wie warum? <?php interface GenericRepository { public function readTalks(); } class TalkRepository implements GenericRepository { public function readTalks() { } } class TalkService { public function __construct(TalkRepository $repo) { } public function getTalks() { } }
  • 69. Pimple – Constructor Injection Dependency Injection – Was, wie warum? <?php require_once '/path/to/Pimple.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new Pimple(); // define services in container $container['talkRepository'] = function ($c) { return new TalkRepository(); }; $container['talkService'] = function ($c) { return new TalkService($c['talkRepository']); }; // instantiate talkService from container $talkService = $container['talkService'];
  • 70. Pimple – Setter Injection Dependency Injection – Was, wie warum? <?php class Logger { public function doLog($logMsg) { } } class TalkService { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  • 71. Pimple – Setter Injection Dependency Injection – Was, wie warum? <?php require_once '/path/to/Pimple.php'; require_once '/path/to/TalkService.php'; // create the Container $container = new Pimple(); // define services in container $container['logger'] = function ($c) { return new Logger(); }; $container['talkRepository'] = function ($c) { return new TalkRepository(); }; $container['talkService'] = function ($c) { $service = new TalkService($c['talkRepository']); $service->setLogger($c['logger']); return $service; }; // instantiate talkService from container $talkService = $container['talkService'];
  • 72. Dependency Injection – Was, wie warum?
  • 73. ZendDi – Erste Schritte Dependency Injection – Was, wie warum? <?php namespace Acme; class TalkService { public function __construct() { } public function getTalks() { } }
  • 74. ZendDi – Erste Schritte Dependency Injection – Was, wie warum? <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); $service->getTalks();
  • 75. ZendDi – Constructor Injection Dependency Injection – Was, wie warum? <?php namespace Acme; interface GenericRepository { public function readTalks(); } class TalkRepository implements GenericRepository { public function readTalks() { } } class TalkService { public function __construct(TalkRepository $repo) { } public function getTalks() { } }
  • 76. ZendDi – Constructor Injection Dependency Injection – Was, wie warum? <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); $service->getTalks();
  • 77. ZendDi – Setter Injection Dependency Injection – Was, wie warum? <?php namespace Acme; class Logger { public function doLog($logMsg) { } } class TalkService { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  • 78. ZendDi – Setter Injection Dependency Injection – Was, wie warum? <?php $di = new ZendDiDi(); $di->configure( new ZendDiConfiguration( array( 'definition' => array( 'class' => array( 'AcmeTalkService' => array( 'setLogger' => array('required' => true) ) ) ) ) ) ); $service = $di->get('AcmeTalkService'); var_dump($service);
  • 79. ZendDi – Interface Injection Dependency Injection – Was, wie warum? <?php namespace Acme; class Logger { public function doLog($logMsg) { } } interface LoggerAware { public function setLogger(Logger $logger); } class TalkService implements LoggerAware { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  • 80. ZendDi – Interface Injection Dependency Injection – Was, wie warum? <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); $service->getTalks();
  • 81. ZendDi – Grundsätzliches Dependency Injection – Was, wie warum? <?php $di = new ZendDiDi(); $service = $di->get('AcmeTalkService'); var_dump($service); $service2 = $di->get('AcmeTalkService'); var_dump($service2); // same instance as $service $service3 = $di->get( 'AcmeTalkService', array( 'repo' => new AcmeTalkRepository() ) );
  • 82. ZendDi – Builder Definition Dependency Injection – Was, wie warum? <?php // describe dependency $dep = new ZendDiDefinitionBuilderPhpClass(); $dep->setName('AcmeTalkRepository'); // describe class $class = new ZendDiDefinitionBuilderPhpClass(); $class->setName('AcmeTalkService'); // add injection method $im = new ZendDiDefinitionBuilderInjectionMethod(); $im->setName('__construct'); $im->addParameter('repo', 'AcmeTalkRepository'); $class->addInjectionMethod($im); // configure builder $builder = new ZendDiDefinitionBuilderDefinition(); $builder->addClass($dep); $builder->addClass($class);
  • 83. ZendDi – Builder Definition Dependency Injection – Was, wie warum? <?php // add to Di $defList = new ZendDiDefinitionList($builder); $di = new ZendDiDi($defList); $service = $di->get('AcmeTalkService'); var_dump($service);
  • 84. Dependency Injection – Was, wie warum?
  • 85. Symfony2 Dependency Injection – Was, wie warum? <?php namespace AcmeTalkBundleController; use SymfonyBundleFrameworkBundleControllerController; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; class TalkController extends Controller { /** * @Route("/", name="_talk") * @Template() */ public function indexAction() { $service = $this->get('acme.talk.service'); return array(); } }
  • 86. Symfony2 – Konfigurationsdatei Dependency Injection – Was, wie warum? <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> </container> File services.xml in src/Acme/DemoBundle/Resources/config
  • 87. Symfony2 – Constructor Injection Dependency Injection – Was, wie warum? <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <argument type="service" id="acme.talk.repo" /> </service> </services> </container>
  • 88. Symfony2 – Setter Injection Dependency Injection – Was, wie warum? <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.logger" class="AcmeTalkBundleServiceLogger" /> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <argument type="service" id="acme.talk.repo" /> <call method="setLogger"> <argument type="service" id="acme.talk.logger" /> </call> </service> </services> </container>
  • 89. Symfony2 – Setter Injection (optional) Dependency Injection – Was, wie warum? <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.logger" class="AcmeTalkBundleServiceLogger" /> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <argument type="service" id="acme.talk.repo" /> <call method="setLogger"> <argument type="service" id="acme.talk.logger" on-invalid="ignore" /> </call> </service> </services> </container>
  • 90. Symfony2 – Property Injection Dependency Injection – Was, wie warum? <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <services> <service id="acme.talk.repo" class="AcmeTalkBundleServiceTalkRepository" /> <service id="acme.talk.service" class="AcmeTalkBundleServiceTalkService"> <property name="talkRepository" type="service" id="acme.talk.repo" /> </service> </services> </container>
  • 91. Dependency Injection – Was, wie warum?
  • 92. Flow3 – Constructor Injection Dependency Injection – Was, wie warum? <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function __construct( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 93. Flow3 – Setter Injection (manuell) Dependency Injection – Was, wie warum? <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function setTalkService( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 94. Flow3 – Setter Injection (manuell) Dependency Injection – Was, wie warum? File Objects.yaml in Packages/Application/Acme.Demo/Configuration # @package Acme AcmeDemoControllerStandardController: properties: talkService: object: AcmeDemoServiceTalkService
  • 95. Flow3 – Setter Injection (automatisch) Dependency Injection – Was, wie warum? <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function injectTalkService( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  • 96. Dependency Injection – Was, wie warum? Fokus aufs Wesentliche. Keine Ablenkung.
  • 97. Dependency Injection – Was, wie warum? Wiederverwendung steigern.
  • 98. Dependency Injection – Was, wie warum? Hilft den Code besser zu verstehen.
  • 99. Dependency Injection – Was, wie warum? Wieder Spaß bei der Arbeit ;)
  • 100. Dependency Injection – Was, wie warum? Kein Standard. Kein Tooling.
  • 101. Dependency Injection – Was, wie warum? Es braucht Zeit um DI zu verstehen.
  • 102. Dependency Injection – Was, wie warum? Konfiguration vs. Laufzeit