Está en la página 1de 8

10/9/2017 POO: Inyeccin de dependencias (II)

Olvidaste tu usuario o clave? Usuario Contrasea Entrar o registrate Bsqueda personaliza

Foros Blog Tutoriales Cursos Videotutoriales Comic

Publica un tutorial Qu es Cristalab? Tags Ejemplos Anime

Qu quieres buscar? Buscar

Tutoriales / POO: Inyeccin de dependencias (II)

POO: Inyeccin de dependencias (II)


Por Duilio el 02 de Febrero de 2014 con 10,147 visitas 11 Twittear
PHP, MySQL y Servidor Otros tutoriales por Duilio. Like

En mi artculo anterior aprendimos inyeccin de dependencias en Laravel, un concepto bsico de la POO, que permite a unos objetos interactuar con otros
sin crear una dependecia como tal, la cual se inyecta a travs del constructor o de un mtodo setter. Veamos un ejemplo:

Cdigo :

<?php

$db = new MysqlDatabase($host, $user, $password, $options);


$user = new User($db);

$users = $user->selectAll();

Usamos un objeto para conectarnos a una base de datos MySQL y luego lo inyectamos a un objeto User. Si luego quisiramos usar Oracle en teora slo
bastara inyectar un objeto OracleDatabase (con la misma interface de MysqlDatabase). Por lo tanto el manejo de usuarios no est "atado" a MySQL sino que
en teora funcionara con otras bases de datos.

Si no has ledo el artculo anterior hazlo ahora, no te preocupes que el equipo secreto de Cristalab mantendr el servidor
funcionando mientras vuelves

El Problema de la inyeccin de dependencias

Lo anterior parece genial, pero Cul es el truco? Imagina un sistema con 50 tablas distintas y tener que hacer esto cada vez que quieras usar un objeto del
ORM:

Cdigo :

// Muy dificil instanciar un objeto


$db = new MySQLDatabase($host, $user, $password, $options);
$posts = new Post($db);

Contenedores de inyeccin de dependencia o DIC (siglas en ingls)

Si ya el nombre inyeccin de dependencias da miedo, es probable que contenedor de inyeccin de dependencias te haga saltar de la silla y huir del susto,
Pgina guardada
pero en realidad es muy sencillo, tan sencillo que escribir uno en cinco minutos.
Aadir etiquetas

Treinta minutos despus...

http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 1/8
10/9/2017 POO: Inyeccin de dependencias (II)

En un contenedor, usualmente cada clase/objeto es representado por un alias o nombre que es diferente del nombre de la clase original. Por ejemplo el alias
de MysqlDatabase u OracleDatabase sera slo db. La clase User podra ser user (en minsculas) y as

Para instanciar una clase usando el contenedor haremos algo como esto

Cdigo :

$app->make('db'); // O esto:
$app->make('user');

En vez de esto:

Cdigo :

$db = new MysqlDatabase($host, $user, $password, $options);


$user = new User($db);

El contenedor se encargar de resolver el objeto por nosotros (en este caso instanciar -si hace falta- y pasar el objeto de base de datos al usuario).

Por supuesto hay que ensear a nuestro contenedor cmo hacerlo, pero la ventaja es que slo le enseas una vez.

Ensear al contenedor cmo resolver un objeto

A travs de una closure

Esta opcin me parece la ms flexible, tienes un bloque de cdigo para indicarle a PHP cmo debe instanciar la clase (configurar parmetros, etc.) El cdigo
dentro de la closure slo ser ejecutado si llamas a $app->make para el alias en cuestin.

Cdigo :

$app->bind('db', function (Container $app, $options) {


return new MysqlDatabase('local', 'user', 'password', array('engine' => 'innodb'));
});

// Si no se llama a app->make('db') MysqlDatabase nunca se instanciara:


$db = $app->make('db');

Indicando directamente el nombre de la clase

En este caso, al momento de hacer la clase con $app->make tendramos que pasar el array con los parmetros del constructor, til si cada instanciacin es
diferente (aunque en mi contenedor la opcin del closure tambin acepta parmetros).

Cdigo :

$app->bind('db', 'MysqlDatabase');
//Crea una instancia de la base de datos, el array seran los parametros pasados al constructor de MysqlDatabase en este caso:
$db = $app->make('db', array('local', 'user', 'password', array('engine' => 'innodb')));
Pgina guardada
var_dump($db);
Aadir etiquetas

http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 2/8
10/9/2017 POO: Inyeccin de dependencias (II)

Construyendo un objeto fuera del constructor

Menos ptima ya que tenemos que instanciar el objeto slo para pasarlo al contenedor, haga falta o no en la aplicacin como tal:

Cdigo :

$app->instance('db', new MysqlDatabase('local', 'user', 'password', array('engine' => 'innodb')));


$db = $app->make('db');
var_dump($db);

Una instancia singleton

Si necesitamos asegurarnos que un objeto se instancie una sola vez, entonces en vez del mtodo bind usamos el mtodo singleton con los mismos
parmetros, ejemplo:

Cdigo :

$app->singleton('db', function (Container $app, $options) {


return new MysqlDatabase('local', 'user', 'password', array('engine' => 'innodb'));
});

En resumen tenemos 4 mtodos. bind instance y singleton que permiten atar un objeto al contenedor, y make que permite resolverlo y que
usaremos cada vez que necesitemos dicho objeto. Adems recuerden que en el contenedor todos los objetos tendrn un alias, aunque usemos otra clase
los alias siempre sern los mismos, lo cual es muy conveniente.

La clase la hice con una interfaz similar a la de Laravel a propsito, aunque sta es ms sencilla y la intencin no es que la usen en sus proyectos sino que
vean cun simple puede ser un contenedor, por otro lado si no la entienden del todo no hay problema, ms abajo les dejo ejemplos de su implementacin
(que s me interesa que aprendan):

Cdigo :

<?php

class Container {

protected $singleton = array();


protected $bindings = array();

/**
* Bind an object to the container
* @param $name string alias of the class inside the container
* @param $resolver string or closure use to create a new class
* @param bool $singleton whether you need only one instance of the object or several instances
*/
public function bind($name, $resolver, $singleton = false)
{
$this->bindings[$name] = array(
'resolver' => $resolver,
'singleton' => $singleton
);
}
Pgina guardada

/** Aadir etiquetas


* Alias of the bind method using the singleton option
* @param $name string alias of the class inside the container
* @param $resolver string or closure use to create a new class
http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 3/8
10/9/2017 POO: Inyeccin de dependencias (II)
* @param $resolver string or closure use to create a new class
*/
public function singleton($name, $resolver)
{
$this->bind($name, $resolver, true);
}

/**
* Bind an instance of an object to our container
* @param $name string alias of the class inside the container
* @param $object object to be bound
*/
public function instance($name, $object)
{
$this->singleton[$name] = $object;
}

/**
* Create or get an object from the container
* It may be resolved or retrieved from the singleton array
* @param $name string alias of the class inside the container
* @param array $options options to instantiate a new class
* @return object or null
*/
public function make($name, $options = array())
{
if (isset ($this->singleton[$name]))
{
return $this->singleton[$name];
}

if ( ! isset ($this->bindings[$name]))
{
return null;
}

$resolver = $this->bindings[$name]['resolver'];

if (is_string($resolver))
{
$reflection = new ReflectionClass($resolver);
$object = $reflection->newInstanceArgs($options);
}
elseif ($resolver instanceof Closure)
{
$object = $resolver($this, $options);
}

if ($this->bindings[$name]['singleton'])
{
$this->singleton[$name] = $object;
}

return $object;
}

}
Pgina guardada

Aadir etiquetas
Ahora creemos algunos objetos tontos slo para poder hacer uso del contenedor:

http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 4/8
10/9/2017 POO: Inyeccin de dependencias (II)
Cdigo :

class MysqlDatabase {

protected $connection;

public function __construct($host, $user, $password, $options)


{
$this->connection = compact('host', 'user', 'password', 'options');
}
}

class User {
protected $db;
public function __construct($db)
{
$this->db = $db;
}
}

Ok, ahora hagamos el ejemplo del inicio de este post pero usando nuestro contenedor.

1. Instanciamos:

Cdigo :

$app = new Container();

2. Le explicamos al contenedor cmo resolver el alias db:

Cdigo :

$app->singleton('db', function ($app) {


return new MysqlDatabase('local', 'me', 'pony123456', array('engine' => 'innodb'));
});

3. Le explicamos al contenedor cmo resolver el alias user. Noten que dentro del closure hacemos uso del mismo Container para resolver la DB (dado que
user necesita db):

Cdigo :

$app->bind('user', function ($app) {


$db = $app->make('db'); //devolver la DB almacenada en el contenedor
return new User($db);
});

4. Por ltimo haremos (make) un usuario (user) y lanzamos un var_dump:

Cdigo :

Pgina guardada

Aadir etiquetas

http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 5/8
10/9/2017 POO: Inyeccin de dependencias (II)

$user = $app->make('user');
var_dump($user);

Si corren el ejemplo vern que el objeto User fue creado y que dentro de ste se encuentra el objeto MysqlDatabase!

Al usar un contenedor todas las dependencias de un objeto se definen una vez y son reusables y si necesitas cambiar la forma como es instanciado un objeto
slo cambias en un lugar de tu aplicacin y listo.

Cuando no usar un contenedor ni inyeccin de dependencias?

En el caso de que tu aplicacin sea muy sencilla es muy posible que no te haga falta.

Al usar un contenedor mi aplicacin no depende ahora de ste?

Es irnico, la idea es eliminar dependencias y creamos otra, pero es el menor de los males, con l todas las dems clases de nuestra aplicacin quedan
independientes y pueden ser reemplazadas fcilmente.

Otras preguntas en los comentarios o sgueme en Twitter. Si te gust o no, entendiste o no, me gustara saberlo.

En el prximo artculo ahora s me toca hablarles de cmo funciona esto dentro de Laravel, adems de cmo crear una Facade, un ServiceProvider y otros
conceptos propios de Laravel.

Saludos a todos!

Sabes SQL? No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y ms con el Curso Profesional de Bases de Datos que empieza el martes, en
vivo.

Envia un comentario (36)

POO: Inyeccin de dependencias en POO: Inyeccin de dependencias El patrn MVC y sus alternativas
Laravel (III)

Flash CC no soporta AS2. Entra YA a #PlatziConf online... En Mejorando.la decidimos dar La gran historia tras el
ltimo ad... PlatziConf online es una 7 d... rediseo ...
Cuando me enter de que Adobe conferencia en streaming de los Desde el nacimiento de Cristalab Arte y diseo. User Experience y
Flash CC ya no es compatible con mejores ... ha sido mi trabajo y objetivo cr... User Interface. El diseo tiene ...
Ac... Por Freddie Por Freddie Por Freddie
Por caravi

Anterior 1 2

Por geometry dash el 05 de Agosto de 2017

Thanks for your post! Through your pen I found the problem up interesting! I believe there are many other people who are interested in them just like me! Thanks your
shared!... I hope you will continue to have similar posts to share with everyone! I believe a lot of people will be surprised to read this article!
geometry dash

Por slither io el 06 de Agosto de 2017

Your article is awesome! How long does it take to complete this article? I have read through other blogs, but they are cumbersome
Pgina and confusing. I hope you continue
guardada
to have such quality articles to share with everyone! I believe there will be many people who share my views when they read this article from you!
slither io
Aadir etiquetas

http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 6/8
10/9/2017 POO: Inyeccin de dependencias (II)

Por paolo el 07 de Agosto de 2017

Im thoroughly enjoying your blog. I too am an aspiring blog writer but Im still new to the whole thing. Do you have any helpful hints for newbie blog writers? Id
certainly appreciate it.
<a href="http://uspstrackingmap.com">usps tracking</a>

Por harada57 el 07 de Agosto de 2017

It's appropriate time to make a few plans for the longer term and it's time to be happy. I've read this publish and if I may I desire to recommend you few attention-
grabbing things or tips. Perhaps you can write next articles relating to this article. I desire to learn more things about it!

Por Susan Nelson el 08 de Agosto de 2017

I read your entire article and I genuinely like it.Thank you for discussing this great post.
* <a href="http://street-view.org/">Street view</a>

Por Michelle el 08 de Agosto de 2017

Thank you for your post!!


* Street view

Por hill climb racing 2 el 16 de Agosto de 2017

Thanks for sharing these useful information! This is really interesting information for me.
-hill climb racing 2

Por Roanld Lee el 25 de Agosto de 2017

I think my browser is old or not supported for the post, i cant seen any image, but i can read the text and i enjoyed the post you shared Custom Tailor in Hong Kong
Digital SLR Camera Lens UK Send Money to Foreign

Por Satta Matka el 01 de Septiembre de 2017

Top Sites For Satta Matka That Can Help You To Win
<a href="http://sattamatka1.net/" title="Matka Result">Matka Result</a>
<a href="http://www.sattamaster.in/" title="Matka Result">Matka Result</a>

Por Satta Matka el 01 de Septiembre de 2017


Pgina guardada
Top Sites For Satta Matka That Can Help You To Win
Satta Matka
Satta Matka Aadir etiquetas
Satta Matka Guessing Forum
Satta Matka Guessing
Time Bazar Jodi Record

http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 7/8
10/9/2017 POO: Inyeccin de dependencias (II)
Kalyan Jodi Record
Kalyan Jodi Record
Main Mumbai Jodi Record
Main Mumbai Jodi Record
Milan Day Jodi Record
Milan Day Jodi Record
Milan Night Jodi Record
Milan Night Jodi Record
Rajdhani Day Jodi Record
Rajdhani Day Jodi Record
Rajdhani Night Jodi Record
Rajdhani Night Jodi Record

Por fff el 07 de Septiembre de 2017

Eventually, souvenir jackets (also known as cheap christian louboutin sukajan in Japanese) evolved past its replica yeezy shoes post-World War II origins. The
jackets became fashionable, popping up not only on the streets of Harajuku and beyond cheap toms shoes as a fashionable accessory, but in high fashion along cat
walks, and more. The souvenir jacket, while disappearing from high fashion these past couple fake rolex sale seasons obviously, has remained a mainstay in day-to-
day style.

Anterior 1 2

Publica tu comentario o puedes...

Tu nombre: Ests registrado en


Cristalab y quieres
Escribe tu nombre o nick S respetuoso. S detallado. publicar tu URL y avatar?

Tu comentario: No escribas con mayusculas ni como


si fuera un SMS. Inicia sesin
Cuentanos en detalle lo quieras opinar
Insultos, trolls y spammers son
siempre eliminados. No ests registrado an
pero quieres hacerlo antes
[b]negrita[/b] de publicar tu comentario?
[img]http://url/imagen.jpg[/img]
[url=direccion]tu enlace[/url]
Publicar Registrate

Blog Foros Tutoriales Tutoriales de Flash Ejemplos .fla Anime Videotutoriales Cursos Curso de Flash Curso de HTML Tags

http://www.cristalab.com/tutoriales/poo-inyeccion-de-dependencias-ii-c112571l/ 8/8

También podría gustarte