• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Dependency Injection in PHP - dwx13
 

Dependency Injection in PHP - dwx13

on

  • 1,203 views

 

Statistics

Views

Total Views
1,203
Views on SlideShare
1,169
Embed Views
34

Actions

Likes
3
Downloads
7
Comments
0

2 Embeds 34

http://lanyrd.com 30
https://twitter.com 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Dependency Injection in PHP - dwx13 Dependency Injection in PHP - dwx13 Presentation Transcript

    • Dependency InjectionWas, 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 ContractDependency Injection – Was, wie warum?
    • Dependency Injection – Was, wie warum?Dependency Injection
    • Dependency Injection – Was, wie warum?Dependency Injection"[...] zur Laufzeit die Abhängigkeiteneines Objekts diesem von einemanderen Objekt als Referenzen zurVerfü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?ConsumerDependency Injection – Was, wie warum?
    • Was ist Dependency Injection?Consumer DependenciesDependency Injection – Was, wie warum?
    • Was ist Dependency Injection?Consumer Dependencies ContainerDependency Injection – Was, wie warum?
    • Was ist Dependency Injection?Consumer Dependencies ContainerDependency Injection – Was, wie warum?
    • sDependency Injection – Was, wie warum?„new“ is evil!
    • <?phpclass 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!<?phpclass 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 notdepend on low-level modules.Both should depend on abstractions."Robert C. MartinDependency Injection – Was, wie warum?
    • Dependency Injection – Was, wie warum?„new“ is evil!<?phpclass 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 stackedDI FrameworkDependency 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<?phpclass MySampleService implements IMySampleService {/*** @var ISampleDao*/private $sampleDao;public function __construct(ISampleDao $sampleDao) {$this->sampleDao = $sampleDao;}}Dependency Injection – Was, wie warum?
    • Setter Injection<?phpclass MySampleService implements IMySampleService {/*** @var ISampleDao*/private $sampleDao;public function setSampleDao(ISampleDao $sampleDao){$this->sampleDao = $sampleDao;}}Dependency Injection – Was, wie warum?
    • Interface Injection<?phpinterface IApplicationContextAware {public function setCtx(IApplicationContext $ctx);}Dependency Injection – Was, wie warum?
    • Interface Injection<?phpclass MySampleService implements IMySampleService,IApplicationContextAware {/*** @var IApplicationContext*/private $ctx;public function setCtx(IApplicationContext $ctx) {$this->ctx = $ctx;}}Dependency Injection – Was, wie warum?
    • Property InjectionDependency Injection – Was, wie warum?
    • Property InjectionDependency 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<?phpclass MySampleService implements IMySampleService {private $sampleDao;/*** @Inject*/public function __construct(ISampleDao $sampleDao){$this->sampleDao = $sampleDao;}}
    • Dependency Injection – Was, wie warum?Annotations<?phpclass 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 - YAMLservices:SampleDao:class: SampleDaoarguments: [app_sample, iSampleId, BoSample]SampleService:class: SampleServicearguments: [@SampleDao]Dependency Injection – Was, wie warum?
    • Externe Konfiguration - PHP<?phpclass 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 KonfigurationDependency Injection – Was, wie warum?
    • Interne vs. Externe KonfigurationDependency Injection – Was, wie warum?Klassenkonfigurationvs.Instanzkonfiguration
    • Dependency Injection – Was, wie warum?Was bringt mir das? Beispiel bitte.
    • Unittesting einfach gemachtDependency Injection – Was, wie warum?
    • Unittesting einfach gemacht<?phprequire_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ägungDependency Injection – Was, wie warum?
    • Eine Klasse, mehrfache AusprägungPage ExporterPage ExporterReleased / PublishedPagesReleased / PublishedPagesWorkingcopyPagesWorkingcopyPagesDependency Injection – Was, wie warum?
    • Eine Klasse, mehrfache Ausprägung<?phpabstract class PageExporter {protected function setPageDao(IPageDao $pageDao) {$this->pageDao = $pageDao;}}Dependency Injection – Was, wie warum?
    • Eine Klasse, mehrfache Ausprägung<?phpabstract class PageExporter {protected function setPageDao(IPageDao $pageDao) {$this->pageDao = $pageDao;}}Zur Erinnerung:Der Vertrag!Dependency Injection – Was, wie warum?
    • Eine Klasse, mehrfache Ausprägung<?phpclass 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 GierkeEine Klasse, mehrfache AusprägungDependency Injection – Was, wie warum?
    • Eine Klasse, mehrfache Ausprägung<?phpclass 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 mockenDependency Injection – Was, wie warum?
    • Externe Services mockenBookingmanagerBookingmanager WS-KonnektorWS-Konnektor WebserviceWebserviceDependency Injection – Was, wie warum?
    • Externe Services mockenBookingmanagerBookingmanager WS-KonnektorWS-Konnektor WebserviceWebserviceDependency Injection – Was, wie warum?Zur Erinnerung:Der Vertrag!
    • Externe Services mockenBookingmanagerBookingmanager FS-KonnektorFS-Konnektor FilesystemFilesystemDependency Injection – Was, wie warum?
    • Externe Services mockenBookingmanagerBookingmanager FS-KonnektorFS-Konnektor FilesystemFilesystemerfüllt denVertrag!Dependency Injection – Was, wie warum?
    • Sauberer, lesbarer CodeDependency Injection – Was, wie warum?
    • Sauberer, lesbarer Code<?phpclass 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ängigkeitDependency Injection – Was, wie warum?
    • Keine Framework Abhängigkeit<?phpclass 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 SchritteDependency Injection – Was, wie warum?<?phpclass TalkService {public function __construct() {}public function getTalks() {}}
    • Pimple – Erste SchritteDependency Injection – Was, wie warum?<?phprequire_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 InjectionDependency Injection – Was, wie warum?<?phpinterface GenericRepository {public function readTalks();}class TalkRepository implements GenericRepository {public function readTalks() {}}class TalkService {public function __construct(TalkRepository $repo) {}public function getTalks() {}}
    • Pimple – Constructor InjectionDependency Injection – Was, wie warum?<?phprequire_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 InjectionDependency Injection – Was, wie warum?<?phpclass Logger {public function doLog($logMsg) {}}class TalkService {public function __construct(TalkRepository $repo) {}public function setLogger(Logger $logger) {}public function getTalks() {}}
    • Pimple – Setter InjectionDependency Injection – Was, wie warum?<?phprequire_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 SchritteDependency Injection – Was, wie warum?<?phpnamespace Acme;class TalkService {public function __construct() {}public function getTalks() {}}
    • ZendDi – Erste SchritteDependency Injection – Was, wie warum?<?php$di = new ZendDiDi();$service = $di->get(AcmeTalkService);$service->getTalks();
    • ZendDi – Constructor InjectionDependency Injection – Was, wie warum?<?phpnamespace 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 InjectionDependency Injection – Was, wie warum?<?php$di = new ZendDiDi();$service = $di->get(AcmeTalkService);$service->getTalks();
    • ZendDi – Setter InjectionDependency Injection – Was, wie warum?<?phpnamespace Acme;class Logger {public function doLog($logMsg) {}}class TalkService {public function __construct(TalkRepository $repo) {}public function setLogger(Logger $logger) {}public function getTalks() {}}
    • ZendDi – Setter InjectionDependency 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 InjectionDependency Injection – Was, wie warum?<?phpnamespace 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 InjectionDependency Injection – Was, wie warum?<?php$di = new ZendDiDi();$service = $di->get(AcmeTalkService);$service->getTalks();
    • ZendDi – GrundsätzlichesDependency 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 DefinitionDependency 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 DefinitionDependency 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?
    • Symfony2Dependency Injection – Was, wie warum?<?phpnamespace 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 – KonfigurationsdateiDependency 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/serviceshttp://symfony.com/schema/dic/services/services-1.0.xsd"></container>File services.xml in src/Acme/DemoBundle/Resources/config
    • Symfony2 – Constructor InjectionDependency 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/serviceshttp://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 InjectionDependency 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/serviceshttp://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/serviceshttp://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 InjectionDependency 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/serviceshttp://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 InjectionDependency Injection – Was, wie warum?<?phpnamespace 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?<?phpnamespace 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 AcmeAcmeDemoControllerStandardController:properties:talkService:object: AcmeDemoServiceTalkService
    • Flow3 – Setter Injection (automatisch)Dependency Injection – Was, wie warum?<?phpnamespace 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!