0
Real World Dependency Injection Über mich  Stephan Hochdörfer  Head of IT der bitExpert AG, Mannheim  PHP`ler seit 1999...
Real World Dependency Injection Was sind Dependencies?
Real World Dependency Injection Was sind Dependencies?                          Applikation                  Framework    ...
Real World Dependency Injection Was sind Dependencies?                           Controller  PHP Extensions         Servic...
Real World Dependency Injection Sind Dependencies schlecht?
Real World Dependency Injection Sind Dependencies schlecht?      Dependencies sind nicht schlecht!
Real World Dependency Injection Sind Dependencies schlecht?                Nützlich und sinnvoll!
Real World Dependency Injection Sind Dependencies schlecht?       Fixe Dependencies sind schlecht!
Real World Dependency Injection „new“ is evil! <?php class DeletePage extends Mvc_Action_AAction {    private $pageManager...
Real World Dependency Injection „new“ is evil! <?php class DeletePage extends Mvc_Action_AAction {    private $pageManager...
Real World Dependency Injection        "High-level modules should not         depend on low-level modules.            Both...
Real World Dependency Injection „new“ is evil! <?php class DeletePage extends Mvc_Action_AAction {    private $pageManager...
Real World Dependency Injection Wie verwaltet man Dependencies?
Real World Dependency Injection Automatismus notwendig!     Simple Container        vs.   Full stacked                    ...
Real World Dependency Injection Was ist Dependency Injection?
Real World Dependency Injection Was ist Dependency Injection?   new DeletePage(new PageManager());
Real World Dependency Injection Was ist Dependency Injection?    Consumer
Real World Dependency Injection Was ist Dependency Injection?    Consumer            Dependencies
Real World Dependency Injection Was ist Dependency Injection?    Consumer            Dependencies   Container
Real World Dependency Injection Was ist Dependency Injection?    Consumer            Dependencies   Container
Real World Dependency Injection Constructor Injection <?php class MySampleService implements IMySampleService {   /**    *...
Real World Dependency Injection Setter Injection <?php class MySampleService implements IMySampleService {   /**    * @var...
Real World Dependency Injection Interface Injection <?php interface IApplicationContextAware {   public function setCtx(IA...
Real World Dependency Injection Interface Injection <?php class MySampleService implements IMySampleService, IApplicationC...
Real World Dependency Injection Property Injection              "NEIN NEIN NEIN!"                       David Zülke
Real World Dependency Injection Annotations <?php class MySampleService implements IMySampleService {   private $sampleDao...
Real World Dependency Injection Annotations <?php class MySampleService implements IMySampleService {   private $sampleDao...
Real World Dependency Injection Externe Konfiguration - XML <?xml version="1.0" encoding="UTF-8" ?> <beans>    <bean id="S...
Real World Dependency Injection Externe Konfiguration - YAML services:   SampleDao:     class: SampleDao     arguments: [a...
Real World Dependency Injection Externe Konfiguration - PHP <?php class BeanCache extends Beanfactory_Container_PHP {    p...
Real World Dependency Injection Interne vs. Externe Konfiguration             Klassenkonfiguration                     vs....
Real World Dependency Injection Unittesting einfach gemacht
Real World Dependency Injection Unittesting einfach gemacht <?php require_once PHPUnit/Framework.php; class ServiceTest ex...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung                              Page Exporter              ...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter {   protected function...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter {   protected function...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php class PublishedPageExporter extends PageExporter {...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung     "Only deleted code is good code!"                   ...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php class PageExporter {   public function __construct...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?xml version="1.0" encoding="UTF-8" ?> <beans>    <bean...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php // create ApplicationContext instance $ctx = new A...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II       http://editor.loc/page/[id]/headline/        ht...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II <?php class EditPart extends Mvc_Action_AFormAction {...
Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II <?xml version="1.0" encoding="UTF-8" ?> <beans>    <b...
Real World Dependency Injection Externe Services mocken
Real World Dependency Injection Externe Services mocken                               WS-                                W...
Real World Dependency Injection Externe Services mocken                               WS-                                W...
Real World Dependency Injection Externe Services mocken                                FS-                                ...
Real World Dependency Injection Externe Services mocken                                     FS-                           ...
Real World Dependency Injection Sauberer, lesbarer Code
Real World Dependency Injection Sauberer, lesbarer Code <?php class DeletePage extends Mvc_Action_AAction {    private $pa...
Real World Dependency Injection Keine Framework Abhängigkeit
Real World Dependency Injection Keine Framework Abhängigkeit <?php class MySampleService implements IMySampleService {   p...
Real World Dependency Injection   Wie sieht das nun in der Praxis aus?
Real World Dependency Injection                          Pimple
Real World Dependency Injection Pimple – Erste Schritte <?php class TalkService {     public function __construct() {     ...
Real World Dependency Injection Pimple – Erste Schritte <?php require_once /path/to/Pimple.php; require_once /path/to/Talk...
Real World Dependency Injection Pimple – Constructor Injection <?php interface GenericRepository {     public function rea...
Real World Dependency Injection Pimple – Constructor Injection <?php require_once /path/to/Pimple.php; require_once /path/...
Real World Dependency Injection Pimple – Setter Injection <?php class Logger {     public function doLog($logMsg) {     } ...
Real World Dependency Injection Pimple – Setter Injection <?php require_once /path/to/Pimple.php; require_once /path/to/Ta...
Real World Dependency Injection Pimple – Allgemeines <?php require_once /path/to/Pimple.php; require_once /path/to/TalkSer...
Real World Dependency Injection                          Bucket
Real World Dependency Injection Bucket – Constructor Injection <?php interface GenericRepository {     public function rea...
Real World Dependency Injection Bucket – Constructor Injection <?php require_once /path/to/bucket.inc.php; require_once /p...
Real World Dependency Injection ZendDi – Erste Schritte <?php namespace Acme; class TalkService {     public function __co...
Real World Dependency Injection ZendDi – Erste Schritte <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService); ...
Real World Dependency Injection ZendDi – Constructor Injection <?php namespace Acme; interface GenericRepository {     pub...
Real World Dependency Injection ZendDi – Constructor Injection <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkSer...
Real World Dependency Injection ZendDi – Setter Injection <?php namespace Acme; class Logger {     public function doLog($...
Real World Dependency Injection ZendDi – Setter Injection <?php $di = new ZendDiDi(); $di->configure(     new ZendDiConfig...
Real World Dependency Injection ZendDi – Interface Injection <?php namespace Acme; class Logger {     public function doLo...
Real World Dependency Injection ZendDi – Interface Injection <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkServi...
Real World Dependency Injection ZendDi – Grundsätzliches <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService);...
Real World Dependency Injection ZendDi – Builder Definition <?php // describe dependency $dep = new ZendDiDefinitionBuilde...
Real World Dependency Injection ZendDi – Builder Definition      <?php      // add to Di      $defList = new ZendDiDefinit...
Real World Dependency Injection    ZendServiceManager to the resuce!
Real World Dependency Injection Symfony2 <?php namespace AcmeTalkBundleController; use SymfonyBundleFrameworkBundleControl...
Real World Dependency Injection Symfony2 – Konfigurationsdatei File services.xml in src/Acme/DemoBundle/Resources/config <...
Real World Dependency Injection Symfony2 – Constructor Injection <?xml version="1.0" ?> <container xmlns="http://symfony.c...
Real World Dependency Injection Symfony2 – Setter Injection <?xml version="1.0" ?> <container xmlns="http://symfony.com/sc...
Real World Dependency Injection Symfony2 – Setter Injection (optional) <?xml version="1.0" ?> <container xmlns="http://sym...
Real World Dependency Injection Symfony2 – Property Injection <?xml version="1.0" ?> <container xmlns="http://symfony.com/...
Real World Dependency Injection Symfony2 – private / öffentliche Services <?xml version="1.0" ?> <container xmlns="http://...
Real World Dependency Injection Symfony2 – Vererbung <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/di...
Real World Dependency Injection Symfony2 – Scoping <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/...
Real World Dependency Injection
Real World Dependency Injection Flow3 – Constructor Injection <?php namespace AcmeDemoController; use TYPO3FLOW3Annotation...
Real World Dependency Injection Flow3 – Constructor Injection (manuell) <?php namespace AcmeDemoController; use TYPO3FLOW3...
Real World Dependency Injection Flow3 – Setter Injection (manuell) <?php namespace AcmeDemoController; use TYPO3FLOW3Annot...
Real World Dependency Injection Flow3 – Setter Injection (manuell) File Objects.yaml in Packages/Application/Acme.Demo/Con...
Real World Dependency Injection Flow3 – Setter Injection (automatisch) <?php namespace AcmeDemoController; use TYPO3FLOW3A...
Real World Dependency Injection Flow3 – Setter Injection (automatisch) <?php namespace AcmeDemoController; use TYPO3FLOW3A...
Real World Dependency Injection Flow3 – Property Injection <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations a...
Real World Dependency Injection Flow3 – Property Injection (mittels Interface) <?php namespace AcmeDemoController; use TYP...
Real World Dependency Injection Flow3 – Property Injection (mittels Interface) File Objects.yaml in Packages/Application/A...
Real World Dependency Injection Flow3 – Scoping <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /*...
Real World Dependency Injection Vorteile              Lose Kopplung,    gesteigerte Wiederverwendbarkeit !
Real World Dependency Injection Vorteile           Codeumfang reduzieren,          Fokus auf das Wesentliche!
Real World Dependency Injection Vorteile          Hilft Entwicklern den Code              besser zu verstehen!
Real World Dependency Injection Nachteile – Kein JSR330 für PHP         Bucket, Crafty, FLOW3, Imind_Context, PicoContaine...
Real World Dependency Injection Nachteile – Entwickler müssen umdenken             Konfiguration ↔ Laufzeit
Vielen Dank!
Image Creditshttp://www.sxc.hu/photo/1028452
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
Upcoming SlideShare
Loading in...5
×

Real World Dependency Injection - phpugffm13

2,900

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,900
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
6
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "Real World Dependency Injection - phpugffm13"

  1. 1. Real World Dependency Injection Über mich  Stephan Hochdörfer  Head of IT der bitExpert AG, Mannheim  PHP`ler seit 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  2. 2. Real World Dependency Injection Was sind Dependencies?
  3. 3. Real World Dependency Injection Was sind Dependencies? Applikation Framework Bibliotheken
  4. 4. Real World Dependency Injection Was sind Dependencies? Controller PHP Extensions Service / Model Utils Datastore(s)
  5. 5. Real World Dependency Injection Sind Dependencies schlecht?
  6. 6. Real World Dependency Injection Sind Dependencies schlecht? Dependencies sind nicht schlecht!
  7. 7. Real World Dependency Injection Sind Dependencies schlecht? Nützlich und sinnvoll!
  8. 8. Real World Dependency Injection Sind Dependencies schlecht? Fixe Dependencies sind schlecht!
  9. 9. 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) ); } }
  10. 10. 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) ); } }
  11. 11. Real World Dependency Injection "High-level modules should not depend on low-level modules. Both should depend on abstractions." Robert C. Martin
  12. 12. 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) ); } }
  13. 13. Real World Dependency Injection Wie verwaltet man Dependencies?
  14. 14. Real World Dependency Injection Automatismus notwendig! Simple Container vs. Full stacked DI Framework
  15. 15. Real World Dependency Injection Was ist Dependency Injection?
  16. 16. Real World Dependency Injection Was ist Dependency Injection? new DeletePage(new PageManager());
  17. 17. Real World Dependency Injection Was ist Dependency Injection? Consumer
  18. 18. Real World Dependency Injection Was ist Dependency Injection? Consumer Dependencies
  19. 19. Real World Dependency Injection Was ist Dependency Injection? Consumer Dependencies Container
  20. 20. Real World Dependency Injection Was ist Dependency Injection? Consumer Dependencies Container
  21. 21. Real World Dependency Injection Constructor Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  22. 22. Real World Dependency Injection Setter Injection <?php class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao; public function setSampleDao(ISampleDao $sampleDao){ $this->sampleDao = $sampleDao; } }
  23. 23. Real World Dependency Injection Interface Injection <?php interface IApplicationContextAware { public function setCtx(IApplicationContext $ctx); }
  24. 24. Real World Dependency Injection Interface Injection <?php class MySampleService implements IMySampleService, IApplicationContextAware { /** * @var IApplicationContext */ private $ctx; public function setCtx(IApplicationContext $ctx) { $this->ctx = $ctx; } }
  25. 25. Real World Dependency Injection Property Injection "NEIN NEIN NEIN!" David Zülke
  26. 26. Real World Dependency Injection Annotations <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  27. 27. Real World Dependency Injection Annotations <?php class MySampleService implements IMySampleService { private $sampleDao; /** * @Inject * @Named(TheSampleDao) */ public function __construct(ISampleDao $sampleDao) { $this->sampleDao = $sampleDao; } }
  28. 28. Real World Dependency Injection 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>
  29. 29. Real World Dependency Injection Externe Konfiguration - YAML services: SampleDao: class: SampleDao arguments: [app_sample, iSampleId, BoSample] SampleService: class: SampleService arguments: [@SampleDao]
  30. 30. Real World Dependency Injection 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; } }
  31. 31. Real World Dependency Injection Interne vs. Externe Konfiguration Klassenkonfiguration vs. Instanzkonfiguration
  32. 32. Real World Dependency Injection Unittesting einfach gemacht
  33. 33. Real World Dependency Injection 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); } }
  34. 34. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung
  35. 35. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung Page Exporter Page Exporter Released / /Published Released Published Workingcopy Workingcopy Pages Pages Pages Pages
  36. 36. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
  37. 37. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php abstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; } } Zur Erinnerung: Der Vertrag!
  38. 38. Real World Dependency Injection 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()); } }
  39. 39. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung "Only deleted code is good code!" Oliver Gierke
  40. 40. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung <?php class PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; } }
  41. 41. Real World Dependency Injection 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>
  42. 42. Real World Dependency Injection 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);
  43. 43. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II
  44. 44. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II http://editor.loc/page/[id]/headline/ http://editor.loc/page/[id]/content/ http://editor.loc/page/[id]/teaser/
  45. 45. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II <?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) { } }
  46. 46. Real World Dependency Injection Eine Klasse, mehrfache Ausprägung II <?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>
  47. 47. Real World Dependency Injection Externe Services mocken
  48. 48. Real World Dependency Injection Externe Services mocken WS- WS- Bookingmanager Bookingmanager Webservice Webservice Konnektor Konnektor
  49. 49. Real World Dependency Injection Externe Services mocken WS- WS- Bookingmanager Bookingmanager Webservice Webservice Konnektor Konnektor Zur Erinnerung: Der Vertrag!
  50. 50. Real World Dependency Injection Externe Services mocken FS- FS- Bookingmanager Bookingmanager Filesystem Filesystem Konnektor Konnektor
  51. 51. Real World Dependency Injection Externe Services mocken FS- FS- Bookingmanager Bookingmanager Filesystem Filesystem Konnektor Konnektor erfüllt den Vertrag!
  52. 52. Real World Dependency Injection Sauberer, lesbarer Code
  53. 53. Real World Dependency Injection 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()); } }
  54. 54. Real World Dependency Injection Keine Framework Abhängigkeit
  55. 55. Real World Dependency Injection 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) {} } }
  56. 56. Real World Dependency Injection Wie sieht das nun in der Praxis aus?
  57. 57. Real World Dependency Injection Pimple
  58. 58. Real World Dependency Injection Pimple – Erste Schritte <?php class TalkService { public function __construct() { } public function getTalks() { } }
  59. 59. Real World Dependency Injection Pimple – Erste Schritte <?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];
  60. 60. Real World Dependency Injection Pimple – Constructor Injection <?php interface GenericRepository { public function readTalks(); } class TalkRepository implements GenericRepository { public function readTalks() { } } class TalkService { public function __construct(TalkRepository $repo) { } public function getTalks() { } }
  61. 61. Real World Dependency Injection Pimple – Constructor Injection <?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];
  62. 62. Real World Dependency Injection Pimple – Setter Injection <?php class Logger { public function doLog($logMsg) { } } class TalkService { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  63. 63. Real World Dependency Injection Pimple – Setter Injection <?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];
  64. 64. Real World Dependency Injection Pimple – Allgemeines <?php require_once /path/to/Pimple.php; require_once /path/to/TalkService.php; // create the Container $container = new Pimple(); // define services in container $container[loggerShared] = $c->share(function ($c) { return new Logger(); )}; $container[logger] = function ($c) { return new Logger(); }; // instantiate logger from container $logger = $container[logger]; // instantiate shared logger from container (same instance!) $logger2 = $container[loggerShared]; $logger3 = $container[loggerShared];
  65. 65. Real World Dependency Injection Bucket
  66. 66. Real World Dependency Injection Bucket – Constructor Injection <?php interface GenericRepository { public function readTalks(); } class TalkRepository implements GenericRepository { public function readTalks() { } } class TalkService { public function __construct(TalkRepository $repo) { } public function getTalks() { } }
  67. 67. Real World Dependency Injection Bucket – Constructor Injection <?php require_once /path/to/bucket.inc.php; require_once /path/to/TalkService.php; // create the Container $container = new bucket_Container(); // instantiate talkService from container $talkService = $container->create(TalkService); // instantiate shared instances from container $talkService2 = $container->get(TalkService); $talkService3 = $container->get(TalkService);
  68. 68. Real World Dependency Injection ZendDi – Erste Schritte <?php namespace Acme; class TalkService { public function __construct() { } public function getTalks() { } }
  69. 69. Real World Dependency Injection ZendDi – Erste Schritte <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService); $service->getTalks();
  70. 70. Real World Dependency Injection ZendDi – Constructor Injection <?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() { } }
  71. 71. Real World Dependency Injection ZendDi – Constructor Injection <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService); $service->getTalks();
  72. 72. Real World Dependency Injection ZendDi – Setter Injection <?php namespace Acme; class Logger { public function doLog($logMsg) { } } class TalkService { public function __construct(TalkRepository $repo) { } public function setLogger(Logger $logger) { } public function getTalks() { } }
  73. 73. Real World Dependency Injection ZendDi – Setter Injection <?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);
  74. 74. Real World Dependency Injection ZendDi – Interface Injection <?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() { } }
  75. 75. Real World Dependency Injection ZendDi – Interface Injection <?php $di = new ZendDiDi(); $service = $di->get(AcmeTalkService); $service->getTalks();
  76. 76. Real World Dependency Injection ZendDi – Grundsätzliches <?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 phpbnl12TalkRepository() ) ); var_dump($service3); // new instance
  77. 77. Real World Dependency Injection ZendDi – Builder Definition <?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);
  78. 78. Real World Dependency Injection ZendDi – Builder Definition <?php // add to Di $defList = new ZendDiDefinitionList($builder); $di = new ZendDiDi($defList); $service = $di->get(AcmeTalkService); var_dump($service);
  79. 79. Real World Dependency Injection ZendServiceManager to the resuce!
  80. 80. Real World Dependency Injection Symfony2 <?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(); } }
  81. 81. Real World Dependency Injection Symfony2 – Konfigurationsdatei File services.xml in src/Acme/DemoBundle/Resources/config <?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>
  82. 82. Real World Dependency Injection Symfony2 – Constructor Injection <?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>
  83. 83. Real World Dependency Injection Symfony2 – Setter Injection <?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>
  84. 84. Real World Dependency Injection Symfony2 – Setter Injection (optional) <?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>
  85. 85. Real World Dependency Injection Symfony2 – Property Injection <?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>
  86. 86. Real World Dependency Injection Symfony2 – private / öffentliche Services <?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" public="false" /> <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>
  87. 87. Real World Dependency Injection Symfony2 – Vererbung <?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.serviceparent" class="AcmeTalkBundleServiceTalkService" abstract="true"> <property name="talkRepository" type="service" id="acme.talk.repo" /> </service> <service id="acme.talk.service" parent="acme.talk.serviceparent" /> <service id="acme.talk.service2" parent="acme.talk.serviceparent" /> </services> </container>
  88. 88. Real World Dependency Injection Symfony2 – Scoping <?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" scope="prototype"> <property name="talkRepository" type="service" id="acme.talk.repo" /> </service> </services> </container>
  89. 89. Real World Dependency Injection
  90. 90. Real World Dependency Injection Flow3 – Constructor Injection <?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() { } }
  91. 91. Real World Dependency Injection Flow3 – Constructor Injection (manuell) <?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() { } }
  92. 92. Real World Dependency Injection Flow3 – Setter Injection (manuell) <?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() { } }
  93. 93. Real World Dependency Injection Flow3 – Setter Injection (manuell) File Objects.yaml in Packages/Application/Acme.Demo/Configuration # @package Acme AcmeDemoControllerStandardController: properties: talkService: object: AcmeDemoServiceTalkService
  94. 94. Real World Dependency Injection Flow3 – Setter Injection (automatisch) <?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() { } }
  95. 95. Real World Dependency Injection Flow3 – Setter Injection (automatisch) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface */ protected $talkService; public function injectSomethingElse( AcmeDemoServiceTalkService $talkService) { $this->talkService = $talkService; } public function indexAction() { } }
  96. 96. Real World Dependency Injection Flow3 – Property Injection <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkService * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  97. 97. Real World Dependency Injection Flow3 – Property Injection (mittels Interface) <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  98. 98. Real World Dependency Injection Flow3 – Property Injection (mittels Interface) File Objects.yaml in Packages/Application/Acme.Demo/Configuration # @package Acme AcmeDemoServiceTalkServiceInterface: className: AcmeDemoServiceTalkService
  99. 99. Real World Dependency Injection Flow3 – Scoping <?php namespace AcmeDemoController; use TYPO3FLOW3Annotations as FLOW3; /** * @FLOW3Scope("session") */ class StandardController extends TYPO3FLOW3MVCControllerActionController { /** * @var AcmeDemoServiceTalkServiceInterface * @FLOW3Inject */ protected $talkService; public function indexAction() { } }
  100. 100. Real World Dependency Injection Vorteile Lose Kopplung, gesteigerte Wiederverwendbarkeit !
  101. 101. Real World Dependency Injection Vorteile Codeumfang reduzieren, Fokus auf das Wesentliche!
  102. 102. Real World Dependency Injection Vorteile Hilft Entwicklern den Code besser zu verstehen!
  103. 103. Real World Dependency Injection Nachteile – Kein JSR330 für PHP Bucket, Crafty, FLOW3, Imind_Context, PicoContainer, Pimple, Phemto, Stubbles, Symfony 2.0, Sphicy, Solar, Substrate, XJConf, Yadif, ZendDi , Lion Framework, Spiral Framework, Xyster Framework, …
  104. 104. Real World Dependency Injection Nachteile – Entwickler müssen umdenken Konfiguration ↔ Laufzeit
  105. 105. Vielen Dank!
  106. 106. Image Creditshttp://www.sxc.hu/photo/1028452
  1. A particular slide catching your eye?

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

×