INJECTION DE
DÉPENDANCES,
CONTAINERS & PHP-DI
BONJOUR

MATTHIEU NAPOLI
My C-Sense ( myclabs ), Lyon
mnapoli.fr / @matthieunapoli
github.com/mnapoli

PHP-DI
Container d'...
DI ≠ DIC
INJECTION DE DÉPENDANCES
Construire son code pour ne plus créer ses dépendances
=> méthode

CONTAINER

Construit des objet...
INJECTION DE
DÉPENDANCES
WORKFLOW D'UN CODE CLASSIQUE
Application :
$foo = new FooController();
$foo->loginAction();

Classe FooController :
public...
WORKFLOW D'UN CODE CLASSIQUE
=> dépendances choisies lors de l'écriture du code (hard-coded)
Tests : tester du code qui ut...
TRANSFORMATION
TRANSFORMATION
Avant :
class FooController {
public function loginAction() {
$bar = new Bar(); // ou $bar = Bar::getInstan...
WORKFLOW D'UN CODE UTILISANT L'INJECTION
DE DÉPENDANCES
Application :
$bim = new Bim();
$bar = new Bar($bim);
$foo = new F...
INVERSION OF CONTROL
=> dépendances choisies lors de l'exécution
Possibilité de remplacer les dépendances injectées
Dans l...
CODE AGAINST INTERFACES
class StoreService {
public function __construct(GeolocationService $geolocationService) { … }
}
i...
MAIS
Nécessite de gérer les dépendances dans l'application
$bim = new Bim();
$bar = new Bar($bim);
$foo = new FooControlle...
CONTAINER
WORKFLOW D'UN CODE UTILISANT UN
CONTAINER
Application :
$foo = $container->get('FooController');
$foo->doSomething();

Cla...
$foo = $container->get('FooController');

=
$bim = new Bim();
$bar = new Bar($bim);
$foo = new FooController($bar);
Le container fait les injections, et aide à construire les graphes d'objets
ATTENTION !
$foo = $container->get('FooController');

Service Locator : anti-pattern
CONFIGURATION DU CONTAINER
Nécessite de configurer le container pour qu'il injecte les bons objets
Chaque container se con...
EXEMPLE SIMPLE
$container = new Container();
$bim = new Bim();
$bar = new Bar($bim);
$container->set('Bim', $bim);
$contai...
CALLBACKS
$container = new Container();
$container->set('Bim', function() {
return new Bim();
});
$container->set('Bar', f...
FICHIERS DE CONFIGURATION
Tableau PHP
YAML
XML
…
Formats différents pour chaque librairie
Symfony DI
ZendDi (+ tous les autres)
Pimple
Aura DI
Laravel
Mouf
Orno
PPI
…
PHP-DI
POURQUOI ?
Pratique
Volontairement copieur
Framework-agnostic
PHP-DI
v1.0 (août 2012) : injections via annotations (PC)
v2.0 (décembre 2012) : refactoring, version stable
v3.0 (avril 2...
REFLECTION
Résolution de dépendances intelligente
class Foo {
public function __construct(Bar $param1) {
}
}

~ 90% des ca...
ANNOTATIONS
Inspiré de Java/Spring
use DIAnnotationInject;
class UserController {
/**
* @Inject
*/
private $userRepository...
CONFIGURATION PHP
$container->set('Bar');
$container->set('Foo')
->withConstructor(array('Bar'));
$container->set('MyInter...
YAML
Bar:
Foo:
constructor: [ Bar ]
MyInterface:
class: MyImplementation
FUTUR
PHP-DI : v4.0, intégration avec d'autres frameworks
PHP-FIG : collaboration pour une PSR ContainerInterface
Communau...
MERCI

Site officiel : php-di.org
GitHub : mnapoli/PHP-DI
Twitter : @PHPDI
Prochain SlideShare
Chargement dans…5
×

[FR] Injection de dépendances, Containers & PHP-DI

572 vues

Publié le

[French]
Présentation du principe d'injection de dépendances, des containers et de PHP-DI.

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
572
Sur SlideShare
0
Issues des intégrations
0
Intégrations
22
Actions
Partages
0
Téléchargements
16
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

[FR] Injection de dépendances, Containers & PHP-DI

  1. 1. INJECTION DE DÉPENDANCES, CONTAINERS & PHP-DI
  2. 2. BONJOUR MATTHIEU NAPOLI My C-Sense ( myclabs ), Lyon mnapoli.fr / @matthieunapoli github.com/mnapoli PHP-DI Container d'injection de dépendances depuis Mars 2012
  3. 3. DI ≠ DIC
  4. 4. INJECTION DE DÉPENDANCES Construire son code pour ne plus créer ses dépendances => méthode CONTAINER Construit des objets et injecte les dépendances => outil
  5. 5. INJECTION DE DÉPENDANCES
  6. 6. WORKFLOW D'UN CODE CLASSIQUE Application : $foo = new FooController(); $foo->loginAction(); Classe FooController : public function loginAction() { $bar = new Bar(); // ou $bar = Bar::getInstance() $bar->doSomething(); } Classe Bar : public function doSomething() { $bim = new Bim(); // ou $bim = Bim::getInstance() $bim->doSomethingElse(); }
  7. 7. WORKFLOW D'UN CODE CLASSIQUE => dépendances choisies lors de l'écriture du code (hard-coded) Tests : tester du code qui utilise un service web, des fichiers, une BDD, du cache, … Extensibilité : mon système de log loggue dans un fichier, j'aimerai qu'il écrive en BDD et les envoie par email… Coupling : je veux changer de système de cache (ou sa config) -> je dois changer le code partout…
  8. 8. TRANSFORMATION
  9. 9. TRANSFORMATION Avant : class FooController { public function loginAction() { $bar = new Bar(); // ou $bar = Bar::getInstance() $bar->doSomething(); } } Après : class FooController { private $bar; public function __construct(Bar $bar) { $this->bar = $bar; } public function loginAction() { $this->bar->doSomething(); } }
  10. 10. WORKFLOW D'UN CODE UTILISANT L'INJECTION DE DÉPENDANCES Application : $bim = new Bim(); $bar = new Bar($bim); $foo = new FooController($bar); $foo->loginAction(); Classe FooController : public function loginAction() { $this->bar->doSomething(); } Classe Bar : public function doSomething() { $this->bim->doSomethingElse(); }
  11. 11. INVERSION OF CONTROL => dépendances choisies lors de l'exécution Possibilité de remplacer les dépendances injectées Dans les classes, on ne gère plus les dépendances, leurs configurations… Code plus générique : code against interfaces
  12. 12. CODE AGAINST INTERFACES class StoreService { public function __construct(GeolocationService $geolocationService) { … } } interface GeolocationService { public function getCoordinates($address); } class GoogleMaps implements GeolocationService { … } class OpenStreetMap implements GeolocationService { … }
  13. 13. MAIS Nécessite de gérer les dépendances dans l'application $bim = new Bim(); $bar = new Bar($bim); $foo = new FooController($bar);
  14. 14. CONTAINER
  15. 15. WORKFLOW D'UN CODE UTILISANT UN CONTAINER Application : $foo = $container->get('FooController'); $foo->doSomething(); Classe FooController : public function loginAction() { $this->bar->doSomething(); } Classe Bar : public function doSomething() { $this->bim->doSomethingElse(); }
  16. 16. $foo = $container->get('FooController'); = $bim = new Bim(); $bar = new Bar($bim); $foo = new FooController($bar);
  17. 17. Le container fait les injections, et aide à construire les graphes d'objets
  18. 18. ATTENTION ! $foo = $container->get('FooController'); Service Locator : anti-pattern
  19. 19. CONFIGURATION DU CONTAINER Nécessite de configurer le container pour qu'il injecte les bons objets Chaque container se configure différement
  20. 20. EXEMPLE SIMPLE $container = new Container(); $bim = new Bim(); $bar = new Bar($bim); $container->set('Bim', $bim); $container->set('Bar', $bar); Problème : initialise tous les objets à chaque requête
  21. 21. CALLBACKS $container = new Container(); $container->set('Bim', function() { return new Bim(); }); $container->set('Bar', function() use ($container) { return new Bar($bim); }); Verbeux, mais efficace
  22. 22. FICHIERS DE CONFIGURATION Tableau PHP YAML XML … Formats différents pour chaque librairie
  23. 23. Symfony DI ZendDi (+ tous les autres) Pimple Aura DI Laravel Mouf Orno PPI …
  24. 24. PHP-DI
  25. 25. POURQUOI ? Pratique Volontairement copieur Framework-agnostic
  26. 26. PHP-DI v1.0 (août 2012) : injections via annotations (PC) v2.0 (décembre 2012) : refactoring, version stable v3.0 (avril 2013) : annotations, config PHP, YAML, … … v3.5 (octobre 2013)
  27. 27. REFLECTION Résolution de dépendances intelligente class Foo { public function __construct(Bar $param1) { } } ~ 90% des cas -> 0 configuration
  28. 28. ANNOTATIONS Inspiré de Java/Spring use DIAnnotationInject; class UserController { /** * @Inject */ private $userRepository; public function loginAction($email, $password) { $user = $this->userRepository->login($email, $password); // ... } } Pas la solution à tout, mais très pratique dans les contrôleurs
  29. 29. CONFIGURATION PHP $container->set('Bar'); $container->set('Foo') ->withConstructor(array('Bar')); $container->set('MyInterface') ->bindTo('MyImplementation');
  30. 30. YAML Bar: Foo: constructor: [ Bar ] MyInterface: class: MyImplementation
  31. 31. FUTUR PHP-DI : v4.0, intégration avec d'autres frameworks PHP-FIG : collaboration pour une PSR ContainerInterface Communauté : diffusion, meilleure doc et best-practices dans ZF2 et Symfony 2…
  32. 32. MERCI Site officiel : php-di.org GitHub : mnapoli/PHP-DI Twitter : @PHPDI

×