Upload
stephan-hochdoerfer
View
2.783
Download
1
Tags:
Embed Size (px)
DESCRIPTION
Citation preview
Real World Dependency Injection
Über mich
Stephan Hochdörfer
Head of IT der bitExpert AG, Mannheim
PHP`ler seit 1999
@shochdoerfer
Real World Dependency Injection
Was sind Dependencies?
Was sind Dependencies?
Applikation
Framework Bibliotheken
Real World Dependency Injection
Was sind Dependencies?
Controller
Service / Model
Datastore(s)
UtilsPHP Extensions
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
<?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'));
}}
Real World Dependency Injection
„new“ is evil!
Real World Dependency Injection
„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 not depend on low-level modules.
Both should depend on abstractions."
Robert C. Martin
Real World Dependency Injection
Real World Dependency Injection
„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?
Real World Dependency Injection
Automatismus notwendig!
Simple Container vs. Full stacked DI Framework
Real World Dependency Injection
Was ist Dependency Injection?
Real World Dependency Injection
Was ist Dependency Injection?
Real World Dependency Injection
new DeletePage(new PageManager());
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 { /** * @var ISampleDao */ private $sampleDao;
public function __construct(ISampleDao $sampleDao) {$this->sampleDao = $sampleDao;
}}
Real World Dependency Injection
Setter Injection<?php
class MySampleService implements IMySampleService { /** * @var ISampleDao */ private $sampleDao;
public function setSampleDao(ISampleDao $sampleDao){$this->sampleDao = $sampleDao;
}}
Real World Dependency Injection
Interface Injection<?php
interface IApplicationContextAware { public function setCtx(IApplicationContext $ctx);}
Real World Dependency Injection
Interface Injection<?php
class MySampleService implements IMySampleService,IApplicationContextAware { /** * @var IApplicationContext */ private $ctx;
public function setCtx(IApplicationContext $ctx) {$this->ctx = $ctx;
}}
Real World Dependency Injection
Property Injection
Real World Dependency Injection
"NEIN NEIN NEIN!"David Zülke
Real World Dependency Injection
Annotations<?php
class MySampleService implements IMySampleService { private $sampleDao;
/** * @Inject */ public function __construct(ISampleDao $sampleDao) {
$this->sampleDao = $sampleDao; }}
Real World Dependency Injection
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>
Real World Dependency Injection
Externe Konfiguration - YAML
services: SampleDao: class: SampleDao arguments: ['app_sample', 'iSampleId', 'BoSample'] SampleService: class: SampleService arguments: [@SampleDao]
Real World Dependency Injection
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;
}}
Real World Dependency Injection
Interne vs. Externe Konfiguration
Real World Dependency Injection
Klassenkonfiguration vs.
Instanzkonfiguration
Unittesting einfach gemacht
Real World Dependency Injection
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);
}}
Real World Dependency Injection
Eine Klasse, mehrfache Ausprägung
Real World Dependency Injection
Eine Klasse, mehrfache Ausprägung
Page ExporterPage Exporter
Released / PublishedPages
Released / PublishedPages
WorkingcopyPages
WorkingcopyPages
Real World Dependency Injection
Eine Klasse, mehrfache Ausprägung<?phpabstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; }}
Real World Dependency Injection
Eine Klasse, mehrfache Ausprägung<?phpabstract class PageExporter { protected function setPageDao(IPageDao $pageDao) { $this->pageDao = $pageDao; }}
Zur Erinnerung: Der Vertrag!
Real World Dependency Injection
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()); }}
Real World Dependency Injection
"Only deleted code is good code!"Oliver Gierke
Eine Klasse, mehrfache Ausprägung
Real World Dependency Injection
Eine Klasse, mehrfache Ausprägung<?phpclass PageExporter { public function __construct(IPageDao $pageDao) { $this->pageDao = $pageDao; }}
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>
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');
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/
http://editor.loc/page/[id]/content/
http://editor.loc/page/[id]/teaser/
Real World Dependency Injection
<?phpclass 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) {}
}
Eine Klasse, mehrfache Ausprägung II
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>
Real World Dependency Injection
Externe Services mocken
Real World Dependency Injection
Externe Services mocken
BookingmanagerBookingmanager WS-Konnektor
WS-Konnektor WebserviceWebservice
Real World Dependency Injection
Externe Services mocken
BookingmanagerBookingmanager WS-Konnektor
WS-Konnektor WebserviceWebservice
Real World Dependency Injection
Zur Erinnerung: Der Vertrag!
Externe Services mocken
BookingmanagerBookingmanager FS-Konnektor
FS-Konnektor FilesystemFilesystem
Real World Dependency Injection
Externe Services mocken
BookingmanagerBookingmanager FS-Konnektor
FS-Konnektor FilesystemFilesystem
erfüllt denVertrag!
Real World Dependency Injection
Sauberer, lesbarer Code
Real World Dependency Injection
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());}
}
Real World Dependency Injection
Keine Framework Abhängigkeit
Real World Dependency Injection
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) {}
}}
Real World Dependency Injection
Real World Dependency Injection
Wie sieht das nun in der Praxis aus?
Real World Dependency Injection
Pimple
Pimple – Erste Schritte
Real World Dependency Injection
<?php
class TalkService {public function __construct() {}
public function getTalks() {}
}
Pimple – Erste Schritte
Real World Dependency Injection
<?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 Injection
Real World Dependency Injection
<?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
Real World Dependency Injection
<?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 Injection
Real World Dependency Injection
<?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
Real World Dependency Injection
<?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'];
Pimple – Allgemeines
Real World Dependency Injection
<?phprequire_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'];
Real World Dependency Injection
Bucket
Bucket – Constructor Injection
Real World Dependency Injection
<?php
interface GenericRepository {public function readTalks();
}
class TalkRepository implements GenericRepository {public function readTalks() {}
}
class TalkService {public function __construct(TalkRepository $repo) {}
public function getTalks() {}
}
Bucket – Constructor Injection
Real World Dependency Injection
<?phprequire_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');
Zend\Di – Erste Schritte
Real World Dependency Injection
<?phpnamespace Acme;
class TalkService {public function __construct() {}
public function getTalks() {}
}
Zend\Di – Erste Schritte
Real World Dependency Injection
<?php
$di = new \Zend\Di\Di();
$service = $di->get('Acme\TalkService');$service->getTalks();
Zend\Di – Constructor Injection
Real World Dependency Injection
<?phpnamespace Acme;
interface GenericRepository {public function readTalks();
}
class TalkRepository implements GenericRepository {public function readTalks() {}
}
class TalkService {public function __construct(TalkRepository $repo) {}
public function getTalks() {}
}
Zend\Di – Constructor Injection
Real World Dependency Injection
<?php
$di = new \Zend\Di\Di();
$service = $di->get('Acme\TalkService');$service->getTalks();
Zend\Di – Setter Injection
Real World Dependency Injection
<?phpnamespace Acme;
class Logger {public function doLog($logMsg) {}
}
class TalkService {public function __construct(TalkRepository $repo) {}
public function setLogger(Logger $logger) {}
public function getTalks() {}
}
Zend\Di – Setter Injection
Real World Dependency Injection
<?php$di = new \Zend\Di\Di();$di->configure(
new Zend\Di\Configuration(array(
'definition' => array('class' => array(
'Acme\TalkService' => array('setLogger' => array('required' => true)
))
))
));
$service = $di->get('Acme\TalkService');var_dump($service);
Zend\Di – Interface Injection
Real World Dependency Injection
<?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() {}
}
Zend\Di – Interface Injection
Real World Dependency Injection
<?php
$di = new \Zend\Di\Di();
$service = $di->get('Acme\TalkService');$service->getTalks();
Zend\Di – Grundsätzliches
Real World Dependency Injection
<?php
$di = new \Zend\Di\Di();
$service = $di->get('Acme\TalkService');var_dump($service);
$service2 = $di->get('Acme\TalkService');var_dump($service2); // same instance as $service
$service3 = $di->get('Acme\TalkService',array(
'repo' => new \phpbnl12\TalkRepository())
);var_dump($service3); // new instance
Zend\Di – Builder Definition
Real World Dependency Injection
<?php// describe dependency$dep = new \Zend\Di\Definition\Builder\PhpClass();$dep->setName('Acme\TalkRepository');
// describe class$class = new \Zend\Di\Definition\Builder\PhpClass();$class->setName('Acme\TalkService');
// add injection method$im = new \Zend\Di\Definition\Builder\InjectionMethod();$im->setName('__construct');$im->addParameter('repo', 'Acme\TalkRepository');$class->addInjectionMethod($im);
// configure builder$builder = new \Zend\Di\Definition\BuilderDefinition();$builder->addClass($dep);$builder->addClass($class);
Zend\Di – Builder Definition
Real World Dependency Injection
<?php
// add to Di$defList = new \Zend\Di\DefinitionList($builder);$di = new \Zend\Di\Di($defList);
$service = $di->get('Acme\TalkService');var_dump($service);
Real World Dependency Injection
Zend\ServiceManager to the resuce!
Symfony2
Real World Dependency Injection
<?phpnamespace Acme\TalkBundle\Controller;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class TalkController extends Controller { /** * @Route("/", name="_talk") * @Template() */ public function indexAction() { $service = $this->get('acme.talk.service'); return array(); }}
Symfony2 – Konfigurationsdatei
Real World Dependency 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/serviceshttp://symfony.com/schema/dic/services/services-1.0.xsd">
</container>
File services.xml in src/Acme/DemoBundle/Resources/config
Symfony2 – Constructor Injection
Real World Dependency 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="Acme\TalkBundle\Service\TalkRepository" />
<service id="acme.talk.service" class="Acme\TalkBundle\Service\TalkService">
<argument type="service" id="acme.talk.repo" /></service>
</services></container>
Symfony2 – Setter Injection
Real World Dependency 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="Acme\TalkBundle\Service\Logger" />
<service id="acme.talk.repo" class="Acme\TalkBundle\Service\TalkRepository" />
<service id="acme.talk.service" class="Acme\TalkBundle\Service\TalkService">
<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)
Real World Dependency 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="Acme\TalkBundle\Service\Logger" />
<service id="acme.talk.repo" class="Acme\TalkBundle\Service\TalkRepository" />
<service id="acme.talk.service" class="Acme\TalkBundle\Service\TalkService">
<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
Real World Dependency 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="Acme\TalkBundle\Service\TalkRepository" />
<service id="acme.talk.service" class="Acme\TalkBundle\Service\TalkService">
<property name="talkRepository" type="service" id="acme.talk.repo" />
</service></services>
</container>
Symfony2 – private / öffentliche Services
Real World Dependency 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="Acme\TalkBundle\Service\Logger" public="false" />
<service id="acme.talk.repo" class="Acme\TalkBundle\Service\TalkRepository" />
<service id="acme.talk.service" class="Acme\TalkBundle\Service\TalkService">
<argument type="service" id="acme.talk.repo" /><call method="setLogger">
<argument type="service" id="acme.talk.logger" /></call>
</service></services>
</container>
Symfony2 – Vererbung
Real World Dependency 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.serviceparent"
class="Acme\TalkBundle\Service\TalkService" 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>
Symfony2 – Scoping
Real World Dependency 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="Acme\TalkBundle\Service\TalkRepository" />
<service id="acme.talk.service"class="Acme\TalkBundle\Service\TalkService" scope="prototype"><property name="talkRepository" type="service"
id="acme.talk.repo" /></service>
</services></container>
Real World Dependency Injection
Flow3 – Constructor Injection
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkServiceInterface */protected $talkService;
public function __construct(\Acme\Demo\Service\TalkService $talkService) {$this->talkService = $talkService;
}
public function indexAction() {}
}
Flow3 – Constructor Injection (manuell)
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkServiceInterface */protected $talkService;
public function __construct(\Acme\Demo\Service\TalkService $talkService) {$this->talkService = $talkService;
}
public function indexAction() {}
}
Flow3 – Setter Injection (manuell)
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkServiceInterface */protected $talkService;
public function setTalkService(\Acme\Demo\Service\TalkService $talkService) {$this->talkService = $talkService;
}
public function indexAction() {}
}
Flow3 – Setter Injection (manuell)
Real World Dependency Injection
File Objects.yaml in Packages/Application/Acme.Demo/Configuration# @package AcmeAcme\Demo\Controller\StandardController: properties: talkService: object: Acme\Demo\Service\TalkService
Flow3 – Setter Injection (automatisch)
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkServiceInterface */protected $talkService;
public function injectTalkService(\Acme\Demo\Service\TalkService $talkService) {$this->talkService = $talkService;
}
public function indexAction() {}
}
Flow3 – Setter Injection (automatisch)
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkServiceInterface */protected $talkService;
public function injectSomethingElse(\Acme\Demo\Service\TalkService $talkService) {$this->talkService = $talkService;
}
public function indexAction() {}
}
Flow3 – Property Injection
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkService * @FLOW3\Inject */protected $talkService;
public function indexAction() {}
}
Flow3 – Property Injection (mittels Interface)
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkServiceInterface * @FLOW3\Inject */protected $talkService;
public function indexAction() {}
}
Flow3 – Property Injection (mittels Interface)
Real World Dependency Injection
# @package AcmeAcme\Demo\Service\TalkServiceInterface: className: 'Acme\Demo\Service\TalkService'
File Objects.yaml in Packages/Application/Acme.Demo/Configuration
Flow3 – Scoping
Real World Dependency Injection
<?phpnamespace Acme\Demo\Controller;
use TYPO3\FLOW3\Annotations as FLOW3;
/** * @FLOW3\Scope("session") */class StandardController extends \TYPO3\FLOW3\MVC\Controller\ActionController {
/** * @var \Acme\Demo\Service\TalkServiceInterface * @FLOW3\Inject */protected $talkService;
public function indexAction() {}
}
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, PicoContainer, Pimple,
Phemto, Stubbles, Symfony 2.0, Sphicy, Solar, Substrate, XJConf, Yadif,
Zend\Di , Lion Framework, Spiral Framework, Xyster Framework, …
Real World Dependency Injection
Nachteile – Entwickler müssen umdenken
Konfiguration Laufzeit↔
Real World Dependency Injection
Vielen Dank!
Image Creditshttp://www.sxc.hu/photo/1028452