The state of DI in PHP - phpbnl12

69
The state of DI in PHP

description

 

Transcript of The state of DI in PHP - phpbnl12

Page 1: The state of DI in PHP - phpbnl12

The state of DI in PHP

Page 2: The state of DI in PHP - phpbnl12

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)

[email protected]

@shochdoerfer

Page 3: The state of DI in PHP - phpbnl12

What`s this talk about?

The state of DI in PHP

Page 4: The state of DI in PHP - phpbnl12

What`s this talk about?

The state of DI in PHP

No framework bashing! Hopefully :)

Page 5: The state of DI in PHP - phpbnl12

What`s this talk about?

The state of DI in PHP

It`s all about how DI is implemented.

Page 6: The state of DI in PHP - phpbnl12

What`s DI about?

The state of DI in PHP

Page 7: The state of DI in PHP - phpbnl12

The state of DI in PHP

Inversion of control

Page 8: The state of DI in PHP - phpbnl12

The state of DI in PHP

„Hollywood principle“

Page 9: The state of DI in PHP - phpbnl12

What`s DI about?

The state of DI in PHP

new TalkService(new TalkRepository());

Page 10: The state of DI in PHP - phpbnl12

What`s DI about?

Consumer

The state of DI in PHP

Page 11: The state of DI in PHP - phpbnl12

What`s DI about?

Consumer Dependencies

The state of DI in PHP

Page 12: The state of DI in PHP - phpbnl12

What`s DI about?

Consumer Dependencies Container

The state of DI in PHP

Page 13: The state of DI in PHP - phpbnl12

What`s DI about?

Consumer Dependencies Container

The state of DI in PHP

Page 14: The state of DI in PHP - phpbnl12

A little bit of history...

The state of DI in PHP

Page 15: The state of DI in PHP - phpbnl12

1988

The state of DI in PHP

„Designing Reusable Classes“Ralph E. Johnson & Brian Foote

Page 16: The state of DI in PHP - phpbnl12

1996

The state of DI in PHP

„The Dependency Inversion Principle“Robert C. Martin

Page 17: The state of DI in PHP - phpbnl12

2002

The state of DI in PHP

Page 18: The state of DI in PHP - phpbnl12

2003

The state of DI in PHP

Spring Framework 0.9 released

Page 19: The state of DI in PHP - phpbnl12

2004

The state of DI in PHP

„Inversion of Control Containers and the Dependency Injection pattern“

Martin Fowler

Page 20: The state of DI in PHP - phpbnl12

2004

The state of DI in PHP

Spring Framework 1.0 released

Page 21: The state of DI in PHP - phpbnl12

2004

The state of DI in PHP

PHP 5.0 released

Page 22: The state of DI in PHP - phpbnl12

2005 / 2006

The state of DI in PHP

Garden, a lightweight DI container for PHP.

Page 23: The state of DI in PHP - phpbnl12

2006

The state of DI in PHP

First PHP5 framework with DI support

Page 24: The state of DI in PHP - phpbnl12

2007

The state of DI in PHP

International PHP Conference 2007 features 2 talks about DI.

Page 25: The state of DI in PHP - phpbnl12

2009

The state of DI in PHP

PHP 5.3.0 released

Page 26: The state of DI in PHP - phpbnl12

2010

The state of DI in PHP

Fabien Potencier talks about „Dependency Injection in

PHP 5.2 and 5.3“

Page 27: The state of DI in PHP - phpbnl12

2011

The state of DI in PHP

Symfony2, Flow3, Zend Framework 2 (beta)

Page 28: The state of DI in PHP - phpbnl12

2012

The state of DI in PHP

And now?

Page 29: The state of DI in PHP - phpbnl12

The state of DI in PHP

DI has finally arrived in the PHP world!

Page 30: The state of DI in PHP - phpbnl12

The state of DI in PHP

Let`s have a look at the different implementations!

Page 31: The state of DI in PHP - phpbnl12

The state of DI in PHP

Page 32: The state of DI in PHP - phpbnl12

Zend\Di – First steps

The state of DI in PHP

<?phpnamespace Acme;

class TalkService {public function __construct() {}

public function getTalks() {}

}

Page 33: The state of DI in PHP - phpbnl12

Zend\Di – First steps

The state of DI in PHP

<?php

$di = new \Zend\Di\Di();

$service = $di->get('Acme\TalkService');$service->getTalks();

Page 34: The state of DI in PHP - phpbnl12

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() {}

}

Page 35: The state of DI in PHP - phpbnl12

Zend\Di – Constructor Injection

The state of DI in PHP

<?php

$di = new \Zend\Di\Di();

$service = $di->get('Acme\TalkService');$service->getTalks();

Page 36: The state of DI in PHP - phpbnl12

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() {}

}

Page 37: The state of DI in PHP - phpbnl12

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);

Page 38: The state of DI in PHP - phpbnl12

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() {}

}

Page 39: The state of DI in PHP - phpbnl12

Zend\Di – Interface Injection

The state of DI in PHP

<?php

$di = new \Zend\Di\Di();

$service = $di->get('Acme\TalkService');$service->getTalks();

Page 40: The state of DI in PHP - phpbnl12

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

Page 41: The state of DI in PHP - phpbnl12

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);

Page 42: The state of DI in PHP - phpbnl12

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);

Page 43: The state of DI in PHP - phpbnl12

The state of DI in PHP

Page 44: The state of DI in PHP - phpbnl12

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(); }}

Page 45: The state of DI in PHP - phpbnl12

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

Page 46: The state of DI in PHP - phpbnl12

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>

Page 47: The state of DI in PHP - phpbnl12

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>

Page 48: The state of DI in PHP - phpbnl12

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>

Page 49: The state of DI in PHP - phpbnl12

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>

Page 50: The state of DI in PHP - phpbnl12

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>

Page 51: The state of DI in PHP - phpbnl12

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>

Page 52: The state of DI in PHP - phpbnl12

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>

Page 53: The state of DI in PHP - phpbnl12

The state of DI in PHP

Page 54: The state of DI in PHP - phpbnl12

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() {}

}

Page 55: The state of DI in PHP - phpbnl12

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() {}

}

Page 56: The state of DI in PHP - phpbnl12

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() {}

}

Page 57: The state of DI in PHP - phpbnl12

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

Page 58: The state of DI in PHP - phpbnl12

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() {}

}

Page 59: The state of DI in PHP - phpbnl12

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() {}

}

Page 60: The state of DI in PHP - phpbnl12

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() {}

}

Page 61: The state of DI in PHP - phpbnl12

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() {}

}

Page 62: The state of DI in PHP - phpbnl12

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

Page 63: The state of DI in PHP - phpbnl12

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() {}

}

Page 64: The state of DI in PHP - phpbnl12

The future?

The state of DI in PHP

Page 65: The state of DI in PHP - phpbnl12

The future (or what`s missing)?

The state of DI in PHP

Page 66: The state of DI in PHP - phpbnl12

The state of DI in PHP

PSR for DI container missing!

Page 67: The state of DI in PHP - phpbnl12

The state of DI in PHP

IDE support is missing...

Page 68: The state of DI in PHP - phpbnl12

Thank you!

Page 69: The state of DI in PHP - phpbnl12

http://joind.in/4768