+ All Categories
Home > Technology > Desymfony2013.gonzalo123

Desymfony2013.gonzalo123

Date post: 11-Nov-2014
Category:
Upload: gonzalo-ayuso
View: 5,344 times
Download: 0 times
Share this document with a friend
Description:
Mi charla sobre Dependencias y Contenedores de inyección en la conferencia deSymfony 2013
Popular Tags:
37
Transcript
Page 1: Desymfony2013.gonzalo123
Page 2: Desymfony2013.gonzalo123
Page 3: Desymfony2013.gonzalo123

PHP (83%)JavaScript (10%)Python (1%)VimL (1%)C# (1%)Shell (1%)

@gonzalo123http://gonzalo123.comhttps://github.com/gonzalo123http://www.linkedin.com/in/gonzaloayuso

Hello my name is ...

Gonzalo Ayuso

(according to github)

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 4: Desymfony2013.gonzalo123

http://gonzalo123.comhttp://katayunos.com

You can find me at ...

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 5: Desymfony2013.gonzalo123

Why should we use Dependency Injection?

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 6: Desymfony2013.gonzalo123

S Single responsibilityO Open/closed principle

L Liskov substitutionI Interface segregation

D Dependency inversion principle

S.O.L.I.D.

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 7: Desymfony2013.gonzalo123

IoC and TDD

Dependency injection is a requirement if you want to write testable code.

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 8: Desymfony2013.gonzalo123

class Order{ public function generateOrderForUser($user) { $backend = new BackendOrder('dsn:...'); $orderId = $backend->createOrder();

$pdfGenerator = new PDFGenerator(); $pdf = $pdfGenerator->getPDF($orderId);

$mailer = new Mailer('mailCredentials...'); $mailer->sendPdfToUSer($pdf, $user); }}

$order = new Order();

$order->generateOrderForUser('Gonzalo');

One example. It works but ...

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 9: Desymfony2013.gonzalo123

class Order{ public function generateOrderForUser($user) { $backend = new BackendOrder('dsn:...'); $orderId = $backend->createOrder();

$pdfGenerator = new PDFGenerator(); $pdf = $pdfGenerator->getPDF($orderId);

$mailer = new Mailer('mailCredentials...'); $mailer->sendPdfToUSer($pdf, $user); }}

$order = new Order();

$order->generateOrderForUser('Gonzalo');

Be decoupled my friend

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 10: Desymfony2013.gonzalo123

class Order{ public function generateOrderForUser($user) { $backend = new BackendOrder('dsn:...'); $orderId = $backend->createOrder();

$pdfGenerator = new PDFGenerator(); $pdf = $pdfGenerator->getPDF($orderId);

$mailer = new Mailer('mailCredentials...'); $mailer->sendPdfToUSer($pdf, $user); }}

$order = new Order();

$order->generateOrderForUser('Gonzalo');

Magic strings are evil

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 11: Desymfony2013.gonzalo123

class Order{ public function generateOrderForUser($user) { $backend = new BackendOrder('dsn:...'); $orderId = $backend->createOrder();

$pdfGenerator = new PDFGenerator(); $pdf = $pdfGenerator->getPDF($orderId);

$mailer = new Mailer('mailCredentials...'); $mailer->sendPdfToUSer($pdf, $user); }}

$order = new Order();

$order->generateOrderForUser('Gonzalo');

Can we change anything?

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 12: Desymfony2013.gonzalo123

class Order{ public function generateOrderForUser($user) { $backend = new BackendOrder('dsn:...'); $orderId = $backend->createOrder();

$pdfGenerator = new PDFGenerator(); $pdf = $pdfGenerator->getPDF($orderId);

// remember to remove this comment when we deploy //$mailer = new Mailer('mailCredentials...'); //$mailer->sendPdfToUSer($pdf, $user); }}

$order = new Order();

$order->generateOrderForUser('Gonzalo');

Can we change anything?Open/Close Principle

Desymfony 2013. Madrid @gonzalo123 http://gonzalo123.com

Page 13: Desymfony2013.gonzalo123

class Order{ private $backend, $pdf, $mailer; public function __construct(BackendOrder $backend, PDFGenerator $pdf, Mailer $mailer) { $this->backend = $backend; $this->pdf = $pdf; $this->mailer = $mailer; } public function generateOrderForUser($user) { $orderId = $this->backend->createOrder(); $pdf = $this->pdfGenerator->getPDF($orderId); $this->mailer->sendPdfToUSer($pdf, $user); }}$backend = new BackendOrder('dsn:...');$pdfGenerator = new PDFGenerator();$mailer = new Mailer('mailCredentials...');

$order = new Order($backend, $pdfGenerator, $mailer);$order->generateOrderForUser('Gonzalo');

Refactor -> DI

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 14: Desymfony2013.gonzalo123

class Order{ private $backend, $pdf, $mailer; public function __construct(BackendOrder $backend, PDFGenerator $pdf, Mailer $mailer) { $this->backend = $backend; $this->pdf = $pdf; $this->mailer = $mailer; } public function generateOrderForUser($user) { $orderId = $this->backend->createOrder(); $pdf = $this->pdfGenerator->getPDF($orderId); $this->mailer->sendPdfToUSer($pdf, $user); }}$backend = new BackendOrder('dsn:...');$pdfGenerator = new PDFGenerator();$mailer = new Mailer('mailCredentials...');

$order = new Order($backend, $pdfGenerator, $mailer);$order->generateOrderForUser('Gonzalo');

Refactor -> DI

And that's

all folks!

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 15: Desymfony2013.gonzalo123

The Hollywood principle

"Don't call us, we'll call you."

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 16: Desymfony2013.gonzalo123

class Order{ private $backend, $pdf, $mailer; public function __construct(BackendOrder $backend, PDFGenerator $pdf, Mailer $mailer) { $this->backend = $backend; $this->pdf = $pdf; $this->mailer = $mailer; } public function generateOrderForUser($user) { $orderId = $this->backend->createOrder(); $pdf = $this->pdfGenerator->getPDF($orderId); $this->mailer->sendPdfToUSer($pdf, $user); }}$backend = new BackendOrder('dsn:...');$pdfGenerator = new PDFGenerator();$mailer = new Mailer('mailCredentials...');

$order = new Order($backend, $pdfGenerator, $mailer);$order->generateOrderForUser('Gonzalo');

Where is the problem now?

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 17: Desymfony2013.gonzalo123

class Order{ private $backend, $pdf, $mailer; public function __construct(BackendOrder $backend, PDFGenerator $pdf, Mailer $mailer) { $this->backend = $backend; $this->pdf = $pdf; $this->mailer = $mailer; } public function generateOrderForUser($user) { $orderId = $this->backend->createOrder(); $pdf = $this->pdfGenerator->getPDF($orderId); $this->mailer->sendPdfToUSer($pdf, $user); }}$backend = new BackendOrder('dsn:...');$pdfGenerator = new PDFGenerator();$mailer = new Mailer('mailCredentials...');

$order = new Order($backend, $pdfGenerator, $mailer);$order->generateOrderForUser('Gonzalo');

What can we do?

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 18: Desymfony2013.gonzalo123

Dependency Injection Containers (DIC) to the rescue!

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 19: Desymfony2013.gonzalo123

Dependency Injection Containers (DIC) in PHP? Are u crazy?

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 20: Desymfony2013.gonzalo123

Yes! DIC in PHP:

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 21: Desymfony2013.gonzalo123

<?php

class Container {

protected $s=array();

function __set($k, $c) { $this->s[$k]=$c; }

function __get($k) { return $this->s[$k]($this); }

}

TwitteA Dependency Injection Container in a Tweet

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 22: Desymfony2013.gonzalo123

$c = new Container();$c->backend_driver = function () { return 'dsn:...'; };$c->backend = function ($c) { return new BackendOrder($c->backend_driver);};$c->pdfGenerator = function ($c) { return new PDFGenerator();};$c->mailer_credentials = function () { return 'mailCredentials...'; };$c->mailer = function ($c) { return new Mailer($c->mailer_credentials);};$c->order = function ($c) { return new Order($c->backend, $c->pdfGenerator, $c->mailer);};$order = $c->order;$order->generateOrderForUser('Gonzalo');

TwitteA Dependency Injection Container in a Tweet

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 23: Desymfony2013.gonzalo123

$c = new Pimple();

$c['backend_driver'] = 'mysql:...';$c['backend'] = function ($c) { return new BackendOrder($c['backend_driver']);};$c['pdfGenerator'] = function ($c) { return new PDFGenerator();};$c['mailer_credentials'] = 'mailCredentials...';$c['mailer'] = function ($c) { return new Mailer($c['mailer_credentials']);};$c['order'] = function ($c) { return new Order($c['backend'], $c['pdfGenerator'], $c['mailer']);};$order = $c['order'];$order->generateOrderForUser('Gonzalo');

PimpleA Simple Dependency Injection Container for PHP 5.3

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 24: Desymfony2013.gonzalo123

class MyContainer extends Pimple{ public function __construct() { $this['backend_driver'] = 'dsn:...'; $c['backend'] = function ($this) { return new BackendOrder($this['backend_driver']); }; $c['pdfGenerator'] = function ($c) { return new PDFGenerator(); }; $this['mailer_credentials'] = 'mailCredentials...'; $this['mailer'] = function ($this) { return new Mailer($this['mailer_credentials']); }; $this['order'] = function ($this) { return new Order($this['backend'], $this['pdfGenerator'], $this['mailer']); }; }}$c = new MyContainer();$order = $c['order'];$order->generateOrderForUser('Gonzalo');

PimpleA Simple Dependency Injection Container for PHP 5.3

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 25: Desymfony2013.gonzalo123

composer.json

{

"require": {

"symfony/dependency-injection": "v2.3.0",

"symfony/yaml": "v2.3.0",

"symfony/config": "v2.3.0"

}

}

Symfony DIC

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 26: Desymfony2013.gonzalo123

services.ymlparameters: backend.driver: dsn:... mailer.credentials: mailCredentials...

services: backend: class: BackendOrder arguments: [%backend.driver%]

pdfGenerator: class: PDFGenerator

mailer: class: Mailer arguments: [%mailer.credentials%]

order: class: Order arguments: [@backend, @pdfGenerator,@mailer]

Symfony DIC

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 27: Desymfony2013.gonzalo123

index.phpuse Symfony\Component\DependencyInjection\ContainerBuilder;use Symfony\Component\Config\FileLocator;use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

$container = new ContainerBuilder();$loader = new YamlFileLoader($container, new FileLocator(__DIR__));$loader->load('services.yml');

$order = $container->get('order');$order->generateOrderForUser('Gonzalo');

Symfony DIC

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 28: Desymfony2013.gonzalo123

● Symfony2 (Symfony\DependencyInjection)● Zend Framework2 (Zend\Di)● Silex (Pimple)● Laravel (Illuminate\Container)

Modern frameworks and DIC

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 29: Desymfony2013.gonzalo123

Usar contenedores o no usarlos

Use an IoC container wisely, not promiscuously

To use or not to use DIC

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 30: Desymfony2013.gonzalo123

Let's code!

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 31: Desymfony2013.gonzalo123

services.ymlparameters: twig.cache: /path/to/cache/path twig.auto_reload: true

db.dsn: sqlite::memory db.username: username db.password: password

services: database: class: PDO arguments: [%db.dsn%, %db.username%, %db.password%]

Scaling our services.yml

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 32: Desymfony2013.gonzalo123

services.ymlimports: - resource: twig.yml - resource: database.yml

twig.ymlparameters: twig.cache: /path/to/cache/path twig.auto_reload: true

database.ymlparameters: db.dsn: sqlite::memory db.username: username db.password: passwordservices: database: class: PDO arguments: [%db.dsn%, %db.username%, %db.password%, ]

Scaling our services.yml

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 33: Desymfony2013.gonzalo123

require_once __DIR__.'/vendor/autoload.php';

$app = new Silex\Application();

$app->get('/hello/{name}', function($name) { return 'Hello '.strtoupper($name);});

$app->run();

Silex example

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 34: Desymfony2013.gonzalo123

// services.ymlservices: capitalizer: class: Capitalizer

use Symfony\Component\DependencyInjection\ContainerBuilder;use Symfony\Component\Config\FileLocator;use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

$container = new ContainerBuilder();$loader = new YamlFileLoader($container, new FileLocator(__DIR__));$loader->load('services.yml');

$app = new Silex\Application();$app['container'] = $container;

$app->get('/hello/{name}', function($name) use($app) { $capitalizer = $app['container']->get('capitalizer'); return 'Hello '. $capitalizer->toUpper($name);});

$app->run();

Silex example with DIC

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 35: Desymfony2013.gonzalo123

Almost the end ...

● Be decoupled my friend● S.O.L.I.D.● DI is good ● DIC are tools to help us.● PHP has different DICs● Symfony DIC is very

easy to implement, configurable and easy to extend

Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com

Page 36: Desymfony2013.gonzalo123

Thank you! - ¡Gracias! - ¡Eskerrik asko!

Your turn. Questions?Desymfony 2013 Madrid @gonzalo123 http://gonzalo123.com


Recommended