The state of DI in PHP - phpbnl12
-
Upload
stephan-hochdoerfer -
Category
Technology
-
view
2.918 -
download
2
description
Transcript of The state of DI in PHP - phpbnl12
The state of DI in PHP
The state of DI in PHP
About me
Stephan Hochdörfer, bitExpert AG
Department Manager Research Labs
enjoying PHP since 1999
7 years of DI experience (in PHP)
@shochdoerfer
What`s this talk about?
The state of DI in PHP
What`s this talk about?
The state of DI in PHP
No framework bashing! Hopefully :)
What`s this talk about?
The state of DI in PHP
It`s all about how DI is implemented.
What`s DI about?
The state of DI in PHP
The state of DI in PHP
Inversion of control
The state of DI in PHP
„Hollywood principle“
What`s DI about?
The state of DI in PHP
new TalkService(new TalkRepository());
What`s DI about?
Consumer
The state of DI in PHP
What`s DI about?
Consumer Dependencies
The state of DI in PHP
What`s DI about?
Consumer Dependencies Container
The state of DI in PHP
What`s DI about?
Consumer Dependencies Container
The state of DI in PHP
A little bit of history...
The state of DI in PHP
1988
The state of DI in PHP
„Designing Reusable Classes“Ralph E. Johnson & Brian Foote
1996
The state of DI in PHP
„The Dependency Inversion Principle“Robert C. Martin
2002
The state of DI in PHP
2003
The state of DI in PHP
Spring Framework 0.9 released
2004
The state of DI in PHP
„Inversion of Control Containers and the Dependency Injection pattern“
Martin Fowler
2004
The state of DI in PHP
Spring Framework 1.0 released
2004
The state of DI in PHP
PHP 5.0 released
2005 / 2006
The state of DI in PHP
Garden, a lightweight DI container for PHP.
2006
The state of DI in PHP
First PHP5 framework with DI support
2007
The state of DI in PHP
International PHP Conference 2007 features 2 talks about DI.
2009
The state of DI in PHP
PHP 5.3.0 released
2010
The state of DI in PHP
Fabien Potencier talks about „Dependency Injection in
PHP 5.2 and 5.3“
2011
The state of DI in PHP
Symfony2, Flow3, Zend Framework 2 (beta)
2012
The state of DI in PHP
And now?
The state of DI in PHP
DI has finally arrived in the PHP world!
The state of DI in PHP
Let`s have a look at the different implementations!
The state of DI in PHP
Zend\Di – First steps
The state of DI in PHP
<?phpnamespace Acme;
class TalkService {public function __construct() {}
public function getTalks() {}
}
Zend\Di – First steps
The state of DI in PHP
<?php
$di = new \Zend\Di\Di();
$service = $di->get('Acme\TalkService');$service->getTalks();
Zend\Di – Constructor Injection
The state of DI in PHP
<?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
The state of DI in PHP
<?php
$di = new \Zend\Di\Di();
$service = $di->get('Acme\TalkService');$service->getTalks();
Zend\Di – Setter Injection
The state of DI in PHP
<?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
The state of DI in PHP
<?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
The state of DI in PHP
<?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
The state of DI in PHP
<?php
$di = new \Zend\Di\Di();
$service = $di->get('Acme\TalkService');$service->getTalks();
Zend\Di – General usage
The state of DI in PHP
<?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
The state of DI in PHP
<?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
The state of DI in PHP
<?php
// add to Di$defList = new \Zend\Di\DefinitionList($builder);$di = new \Zend\Di\Di($defList);
$service = $di->get('Acme\TalkService');var_dump($service);
The state of DI in PHP
Symfony2
The state of DI in PHP
<?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 – Configuration file
The state of DI in PHP
<?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
The state of DI in PHP
<?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
The state of DI in PHP
<?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)
The state of DI in PHP
<?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
The state of DI in PHP
<?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/public Services
The state of DI in PHP
<?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 – Service inheritance
The state of DI in PHP
<?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 – Service scoping
The state of DI in PHP
<?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>
The state of DI in PHP
Flow3 – Constructor Injection
The state of DI in PHP
<?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 (manually)
The state of DI in PHP
<?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 (manually)
The state of DI in PHP
<?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 (manually)
The state of DI in PHP
File Objects.yaml in Packages/Application/Acme.Demo/Configuration# @package AcmeAcme\Demo\Controller\StandardController: properties: talkService: object: Acme\Demo\Service\TalkService
Flow3 – Setter Injection (Automagic)
The state of DI in PHP
<?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 (Automagic)
The state of DI in PHP
<?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
The state of DI in PHP
<?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 (with Interface)
The state of DI in PHP
<?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 (with Interface)
The state of DI in PHP
# @package AcmeAcme\Demo\Service\TalkServiceInterface: className: 'Acme\Demo\Service\TalkService'
File Objects.yaml in Packages/Application/Acme.Demo/Configuration
Flow3 – Scoping
The state of DI in PHP
<?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() {}
}
The future?
The state of DI in PHP
The future (or what`s missing)?
The state of DI in PHP
The state of DI in PHP
PSR for DI container missing!
The state of DI in PHP
IDE support is missing...
Thank you!
http://joind.in/4768