July 2012 - Posts
Artículo publicado originalmente en
---
En el artículo anterior revisamos uno de los pilares de los patrones de Diseño Orientado a Objetos: "Inyección de Dependencias" en su forma más básica.
C# – INYECCIÓN DE DEPENDENCIAS
Como lo vimos la inyección de dependencias es una herramienta comúnmente utilizada en varios patrones de diseño orientado a objetos y consiste en inyectar comportamientos a componentes.
En este artículo formalizaremos un poco más su definición para de paso definir e implementar un conocido patrón de diseño llamado estrategia.
Los Robots
Imaginemos que tenemos una clase llamada Robot, cada Robot puede realizar una serie de operaciones fundamentales:
Desde luego hay muchas más pero esas serán suficientes para el ejemplo.
Iniciemos con el análisis, en primera instancia revisemos la característica Disparar. Si tenemos un conjunto de Robots donde todos ellos pueden disparar de manera diferente podemos pensar en crear una clase base llamada Robot la cual desde luego implementa la funcionalidad Disparar como virtual o abstract de tal forma que las implementaciones concretas puedan establecer una forma particular de disparar en cada caso.
Existen inicialmente 3 implementaciones de Robot
- RobotVigilante: Dispara como todos los Robot
- RobotMilitar: Dispara como todos los Robot
- RobotCasero: No dispara
Este es nuestro diagrama de clases

Y estas las implementaciones en código:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class Robot
{
public Robot()
{
}
public virtual void Disparar()
{
}
public virtual void Caminar()
{
}
}
public class RobotVigilante : Robot
{
}
public class RobotMilitar : Robot
{
}
public class RobotCasero : Robot
{
public override void Disparar()
{
}
}
|
Este esquema funciona 'bien' pero hay varios problemas que debemos afrontar si pensamos las cosas detenidamente.
- Cada vez que un Robot no dispare debemos sobrescribir el método virtual
- Pueden requerirse Robots que disparen de manera diferente, en cuyo caso también se requiere sobrescribir el método virtual
- Qué pasa con caminar? efectivamente pueden aparecer Robots que no caminen o Robots que lo hagan con un pie o con cuatro.
Teniendo este escenario nos damos cuenta que el propósito inicial por el cual se ha utilizado la herencia se ha desvirtuado, pues no es cierto que todos los Robot hagan las actividades de la misma forma, incluso pueden haber Robots que no hagan una determinada actividad.
La herencia en este punto se nos ha convertido en un problema, ¿ya vieron cual?, puede que no.
El problema es: MANTENIMIIENTO , todos sabemos que crear un programa es solo la primera parte, la segunda parte es mantener ese programa en el tiempo, hacerle mejoras , evolucionarlo etc. Y desde luego en el escenario de los Robots esto también es una necesidad, necesitaremos crear nuevos Robots y modificar los existentes.
Pero al haber utilizado herencia nos encontraremos que algunas cosas habrá que cambiarlas en la clase base y otras en las clases derivadas, peor aún puede haber un grupo de clases derivadas que no utilicen las funcionalidades de la clase base pero que entre ellas si comparten la misma funcionalidad, esto es : tendremos código redundante.
El problema realmente puede ser muy grueso.
La solución clásica
Lo primero que a uno se le viene a la mente para resolver el tema de los Robot que no Disparan o que no Caminan es utilizar interfaces, lo cual suele ser una muy buena idea, sobre todo teniendo en cuenta este principio de diseño.
Programe contra una interfaz no contra implementaciones concretas.
En este sentido hay que ser claro que este principio hace referencia a interfaces desde el punto de vista del diseño de software no de ningún lenguaje en particular y en este sentido entonces una interfaz puede ser en esencia un Súper Tipo:
- Clase Base
- Clase Abstracta
- Interfaz
Podemos crear dos interfaces para identificar que habilidades tiene cada Robot.
*Sorry por los nombres, mi creatividad en ese sentido es limitada.
Esto nos permitirá tener Robots que Caminen , Disparen, que no hagan nada o que solo hagan una de las dos cosas.

Y esta es la implementación...ligeramente más compleja
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
public interface ICaminable
{
void Caminar();
}
public interface IDisparable
{
void Disparar();
}
public class Robot
{
public Robot()
{
}
public virtual void MatarAJohnConnor()
{
}
}
public class RobotVigilante : Robot, ICaminable, IDisparable
{
public void Caminar()
{
}
public void Disparar()
{
}
}
public class RobotMilitar : Robot, ICaminable, IDisparable
{
public void Caminar()
{
}
public void Disparar()
{
}
}
public class RobotCasero : Robot, ICaminable
{
public void Caminar()
{
}
}
public class RobotDetectorDeJohnConnor : Robot, IDisparable
{
public void Disparar()
{
}
}
|
El tema de la complejidad... preocupante, pero más preocupante aún es el hecho que tenemos código redundante ya que aunque varios robots disparen de la misma forma, cada uno tiene su propia implementación.
Así que estamos usando uno de los principios de diseño de software pero algo anda un poco mal, vamos a solucionarlo.
Para los más experimentados el indicio de solución salta a la vista: encapsulamiento.
Pero pongámoslo en el marco del diseño de software, aquí existe otro principio fundamental:
Identificar los aspectos que cambian, y sepárelos de los que se mantienen iguales.
Eso precisamente se hace en POO haciendo uso de encapsulamiento, cosa que los cambios en este objeto no afecten el resto del código de la implementación.
Encapsular, en este caso implica necesariamente crear un objeto nuevo por cada funcionalidad 'que cambia', las funcionalidades que cambian en nuestros Robot son
Estas funcionalidades que cambian las llamaremos en adelante comportamientos, behaviors en inglés. Es tiempo de extraer estos comportamientos en nuevos objetos.
Cada acción ( caminar, disparar), tienen una serie de comportamientos posibles aunque exhiben la misma interfaz, es decir los mismos métodos con los mismos tipos de datos, así que podemos pensar en generalizar dicha interfaz, de tal forma que podamos crear diferentes comportamientos, por ejemplo al caminar:
- CaminarNormal
- CaminarDeMedioLado
O al disparar
- DispararNormal
- DispararAmetralladora
Queda la duda de ¿Qué hacer con los que no caminan o no disparan? esta es la parte más bella
Este es el diagrama de clases de nuestros comportamientos, y abajo la implementación de los Robots

Ahora veamos el código para los comportamientos
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
public interface IDispararBehavior
{
void Disparar();
}
public interface ICaminarBehavior
{
void Caminar();
}
public class CaminarNormal : ICaminarBehavior
{
public void Caminar()
{
}
}
public class CaminarDeMedioLado : ICaminarBehavior
{
public void Caminar()
{
}
}
public class NoCaminar : ICaminarBehavior
{
public void Caminar()
{
}
}
public class DispararNormal : IDispararBehavior
{
public void Disparar()
{
}
}
public class DispararAmetralladora : IDispararBehavior
{
public void Disparar()
{
}
}
public class NoDisparar : IDispararBehavior
{
public void Disparar()
{
}
}
|
Este es el código de implementación de los robots haciendo uso de los comportamientos creados.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
public abstract class Robot
{
protected IDispararBehavior _disparador;
protected ICaminarBehavior _caminador;
public Robot()
{ }
public void Caminar()
{
_caminador.Caminar();
}
public void Disparar()
{
_disparador.Disparar();
}
public virtual void MatarAJohnConnor()
{
}
}
public class RobotVigilante : Robot
{
public RobotVigilante()
{
_disparador = new DispararNormal();
_caminador = new CaminarNormal();
}
}
public class RobotMilitar : Robot
{
public RobotMilitar()
{
_disparador = new DispararAmetralladora();
_caminador = new CaminarDeMedioLado();
}
}
public class RobotCasero : Robot
{
public RobotCasero()
{
_disparador = new NoDisparar();
_caminador = new CaminarNormal();
}
}
public class RobotDetectorDeJohnConnor : Robot
{
public RobotDetectorDeJohnConnor()
{
_disparador = new DispararAmetralladora();
_caminador = new NoCaminar();
}
}
|
Es una solución impecable, pero aún se puede hacer más! lo bueno de tener separados los comportamientos es que nada impide que podamos cambiar dichos comportamientos en tiempo de ejecución... hell yeeaahh!
Supongamos que queremos actualizar el Robot Detector De John Connor para que ahora pueda caminar, como hacerlo? gracias a que hemos programado contra interfaces y hemos encapsulado los comportamientos que cambian, es algo muy sencillo de hacer. Modificando la clase base, exponiendo de manera pública los comportamientos:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
public abstract class Robot
{
IDispararBehavior _disparador;
public IDispararBehavior Disparador
{
get { return _disparador; }
set { _disparador = value; }
}
ICaminarBehavior _caminador;
public ICaminarBehavior Caminador
{
get { return _caminador; }
set { _caminador = value; }
}
public Robot()
{ }
public void Caminar()
{
_caminador.Caminar();
}
public void Disparar()
{
_disparador.Disparar();
}
public virtual void MatarAJohnConnor()
{
}
}
|
Así expuestos podemos crear un objeto de cualquier tipo y modificar eso en tiempo de ejecución!.
|
1
2
3
4
5
6
7
8
9
10
11
|
public static class Programa
{
public static void Main()
{
var connorKiller = new RobotDetectorDeJohnConnor();
connorKiller.MatarAJohnConnor();
connorKiller.Caminador = new CaminarDeMedioLado();
Console.WriteLine("YEAH");
}
}
|
Digamos que ahora se nos ocurre ponernos un poco mas agresivos:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public static class Programa
{
public class CaminadorAPropulsion : ICaminarBehavior
{
public void Caminar()
{
}
}
public static void Main()
{
var connorKiller = new RobotDetectorDeJohnConnor();
connorKiller.MatarAJohnConnor();
connorKiller.Caminador = new CaminarDeMedioLado();
connorKiller.Caminador = new CaminadorAPropulsion();
connorKiller.MatarAJohnConnor();
Console.WriteLine("YEEEEEEEEEEEEAHHHHHHHH");
}
}
|
Te desafío a igualar esto con herencia 
YEEEEEEEEEEEEAHHHHHHHH

Articulo Original tomado de
---
Qué es Inyección de dependencias
La inyección de dependencias o DI por sus siglas en inglés, es una herramienta comunmente utilizada en varios patrones de diseño orientado a objetos, consiste en inyectar comportamientos a componentes.
Esto no es más que extraer responsabilidades a un componente para delegarlas en otro, estableciendo un mecanismo a traves del cual el nuevo componente pueda ser cambiado en tiempo de ejecución. Es conveniente no confundir Inyección de dependencias (DI) con Inversion de Control (IoC) , error muy comunmente cometido que figura especialmente en la web. IoC es un tema para un próximo artículo.
Ejemplo y Explicación detallada
Imaginemos que estamos haciendo un videojuego en cual tenemos un personaje que es un robot, este robot puede realizar acciones de diferentes maneras, por lo cual su cabeza puede ser conectada a infinidad de cuerpos distintos.

Las soluciónes tradicionales desde el punto de vista de POO son diversas, ejemplo:
- Una clase base Robot con un atributo cuerpo, crear varias clases asugnando un atributo Cuerpo diferente en el constructor
- Una clase Robot con un atributo enumeación que le permita cambiar de cuerpo
- Muchas clases cuerpo que heredan de una clase Robot
Sin embargo a la final la responsabilidad del cuerpo y de la cabeza sigue siendo confusa, otro de mis principios favoritos de Diseño Orientado a Objetos es es de “Single Responsability” o mejor
“Un objeto una responsabilidad”
Claramente las soluciones clásicas al problema planteado no ofrecen esa opción.
Qué hacer? Inyección de dependencias tambien puede llamarse inyección de comportamientos, en todo caso es un nombre muy profesional y estilizado, lo cual puede ser intimidante, pero es un nombre preciso. Que sucede cuando te inyectan algo, una vacuna por ejemplo?. Depositan nuevos componentes en tu cuerpo, que pueden modificar el funcionamiento , sin que esto implique que vuelvas a nacer.
De eso mismo se trata la Inyección de Dependencias, colocar dentro de un objeto otros que puedan cambiar su comportamiento, sin que esto implique volver a crear el objeto.
Esto nos permite tener un objeto que puede hacer un conjunto de tareas, cada una de esas tareas es una responsabilidad, que puede ser ejecutada por otro objeto unicamente especialista y dedicado a ello [una responsabilidad], pero ahora tenemos otro diferenciador, El objeto responsable de ejecutar esa única tarea
Puede establecerse en tiempo de ejecución
La implementación habitual en programación es crear un método capaz de establecer el comportamiento, es decir capaz de cambiar el valor de un atributo asignandole una instancia de objeto diferente.
Esta seria una posible implementación de Robot que no utiliza Inyección de Dependencias
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class Robot
{
public Robot() { }
public void Caminar()
{
}
public void Disparar();
public void Volar();
public void BuscarAJhonConnor()
{
}
}
|
Ahora cambiemos la implementación por una que si haga Inyección de dependencias, primero creamos la clase Body la cual será la responsable de ejecutar las acciones del cuerpo:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class Body
{
public void Caminar()
{
}
public void Volar()
{
}
public void Disparar()
{
}
}
|
Seguidamente creamos un Robot que camina por medio de un Body, teniendo atención en delegar las responsabilidades a dicho objeto:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class Robot
{
public Body _body;
public Robot() { }
public void Caminar()
{
if(_body != null)
_body.Caminar();
}
public void Volar()
{
if (_body != null)
_body.Volar();
}
public void Disparar()
{
if (_body != null)
_body.Disparar();
}
public void BuscarAJhonConnor()
{
}
}
|
Como nos podemos dar cuenta el Robot hace todo lo que hacia antes aunque no tiene asignado aún un body, así que establecemos un mecanismo para hacer esto:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public class Robot
{
public Body _body;
public void SetBody(Body newBody)
{
_body = newBody;
}
public Robot() { }
public void Caminar()
{
if(_body != null)
_body.Caminar();
}
public void Volar()
{
if (_body != null)
_body.Volar();
}
public void Disparar()
{
if (_body != null)
_body.Disparar();
}
public void BuscarAJhonConnor()
{
}
}
|
Bueno eso fué muy ‘java’, pongamonos serios y volvamoslo más elegante, fácil de leer y de mantener, más C#. Hagamos uso de propiedades y deshagamonos del private storage
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public class Robot
{
public Body Cuerpo { get; set; }
public Robot() { }
public void Caminar()
{
if (Cuerpo != null)
Cuerpo.Caminar();
}
public void Volar()
{
if (Cuerpo != null)
Cuerpo.Volar();
}
public void Disparar()
{
if (Cuerpo != null)
Cuerpo.Disparar();
}
public void BuscarAJhonConnor()
{
}
}
|
Como se puede observar la clase Robot tiene la acción caminar, pero la responsabilidad es de la clase Body, tambien es claro que el valor de la propiedad Cuerpo lo podemos cambiar en tiempo de ejecución tan solo asignando una instancia diferente a la propiedad Cuerpo. Esta es una primera aproximación a la inyección de dependencias, siendo más formales incluso muchos comportamientos como Volar y Caminar incluso podrían llegar a estar en clases distintas.
Ahora subamos un poco el nivel, con lo aprendido podemos hablar del patrón de estrategia, el tema del próximo artículo. 
articulo original publicado en
-----
WCF – El caso del wsdl con xsd:import schemalocation que no puede ser interpretado desde clientes PHP
o
El caso del wsdl con referencias externas que no puede ser usado en PHP
Este caso esta relacionado con el caso revisado en el artículo:
WCF – El caso del wsdl con referencias externas apuntando al servidor local
Por lo cual es otra anecdota de casos de consultoria
.
Supongamos que creamos un servicio WCF en http://my.webpage.com.co , como ya sabemos cuando creamos servicios con WCF el wsdl no muestra directamente los tipos de dato del servicio, sino que genera referencias a unos schemas xsd donde únicamente estan estos detalles, ejemplo:
|
1
2
3
4
5
6
7
8
9
10
|
<wsdl:types>
</xsd:schema>
</wsdl:types>
|
En otra oportunidad analizaremos el contenido de esas url, pero no es nada complejo.
El problema reside en que muchos clientes SOAP, sobre todo de tecnologías como PHP, no son capaces de interpretar este tipo de schemas xsd dentro de un wsdl, por lo cual la tarea de consumir el servicio WCF en ocasiones complicada
Los clientes SOAP para PHP en su mayoría requieren que el wsdl incorpore TODAS las especificaciones dentro de si, no soportan referencias externas, así que hay que 'aplanar' el wsdl para que todo quede en el mismo archivo.
Hay dos formas de solucionar este problema
- Forma fácil: Utiliza Framework 4.5, en el cual por defecto WCF incluye la opción de consultar el wsd así:http://my.webpage.com.co/MyService.svc?singlewsdl ,lo que es el mismo wsdl de siempre pero sin referencias externas, TODO EN UNO.
- Sino puedes pasarte a Framework 4.5, lo cual es muy probable en escenario empresariales, entonces continua leyendo este artículo.
Esta tarea requiere realizar algunas modificaciones a nivel de behaviors y endpoints, de hecho debes crear nuevos behaviors, no es nada del otro mundo, pero como todo, requiere tiempo, aprendizaje, pruebas etc. y si estas de afán multiplica este efecto por cien.
Por suerte existen personas que les gusta compartir conocimiento y este caso no es la excepción, en CodePlex, encontramos un proyecto llamado:
WCFExtras
Cuyo lema es: "WCF Soap Header support, Xml comments to WSDL annotation and more", a que te suena muy intereante! 
Bien, se los dejo como tema para revisar, este artículo no trata de conocer a fondo WCFExtras, tan solo una pequeña parte para solucionar nuestro lio.
Una de las funcionalidades de WCFExtras es "Single WSDL file", les suena familiar? en efecto esta funcionalidad nos permite 'aplanar' el wsdl para que no tenga referencias externas sino todo incorporado de una vez en un mismo archivo, justo lo que necesitamos.
Cómo se soluciona?
Lo primero que debemos hacer es bajar WCFExtras y compilar la dll, la agregamos al proyecto donde creamos nuestro servicio.
Seguidamente editamos el archivo app.config y adicionamos la siguiente extensión de behaviors
|
1
2
3
4
5
6
7
|
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="wsdlExtensions" type="WCFExtras.Wsdl.WsdlExtensionsConfig, WCFExtras, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
|
Esto ya nos garantiza que podemos acceder a los nuevos behaviors incorporados con WCFExtras. Así que ahora solo basta utilizarlos para nuestro caso puntual, esta es la forma más sencilla de generar un wsdl 'aplanado', simplemente agregamos un behavior en endpointBehaviors, el tipo del behavior es wsdlExtensions y le pasamos como parámetro singleFile=true
|
1
2
3
4
5
6
7
8
|
<behaviors>
<endpointBehaviors>
<behavior>
<wsdlExtensions singleFile="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
</behaviors>
|
Eso es todo, hora de consultar el wsdl de nuevo y... ya no tenemos nada parecido a lo que vimos más arriba, en su lugar encontramos algo como esto inclusive para los tipos complejos:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<wsdl:types>
<xs:schema attributeFormDefault="qualified"
elementFormDefault="qualified"
<xs:element name="anyType"
nillable="true"
type="xs:anyType"/>
<xs:element name="anyURI"
nillable="true"
type="xs:anyURI"/>
<xs:element name="boolean"
nillable="true"
type="xs:boolean"/>
<xs:element name="byte"
nillable="true"
type="xs:byte"/>
<xs:element name="dateTime"
nillable="true"
type="xs:dateTime"/>
</xs:schema>
</wsdl:types>
|
TODA la información ha sido consolidada en el mismo wsdl.
Articulo tomado del original
---
WCF – El caso del wsdl con xsd:import schemalocation apuntando a la url local en lugar de la pública
o
El caso del wsdl con xsd:import schemalocation apuntando a la url local en lugar de la pública
Dentro de mis labores como Arquitecto y Consultor me he encontrado con este caso que es digno de mencionar, y aunque algunos se sorprendan creanme que este escenario es más comun de lo que imaginan.
Supongamos que creamos un servicio WCF en http://my.webpage.com.co ,cuando creamos servicios con WCF el wsdl no muestra directamente los tipos de dato del servicio, sino que genera referencias a unos schemas xsd donde unicamente estan estos detalles, ejemplo:
|
1
2
3
4
5
6
7
8
9
10
|
<wsdl:types>
</xsd:schema>
</wsdl:types>
|
Vieron lo que sucede? las URL de los xsd no estan apuntando a http://my.webpage.com.co sino a la direccion de la red local http://myLocalServer.webpage.com.co .
A primera impresión es un problema de configuración del WCF, y en efecto al modificar algunos parametros podemos hacer que las URL del wsdl aparezcan solo como http://myLocalServer/MyService.svc , incluso podemos modificar la re esddfritura de URL desde el app.comfig para redireccionar este tipo de peticion es de manera correcta,pero no es un problema fácil de solucionar.
En algunas compañías lo que optan por hacer es modificar su firewall y/o configuracion de dominio público para que permita redireccionar las peticiones a la URL adecuada.
Aunque a primera impresión es un problema de WCF, la realidad es otra. Es un problema en la configuración de IIS.
WCF le pide al web server la dirección host principal para poder armar las rutas a los xsd, y allí es donde IIS le envia el nombre de la máquina local. Pero seamos justos... tampoco es un error de IIS.
Imaginate que tienes un servicio que solo se ejecuta dentro de tu empresa, en ese contexto IIS debe devolverte el nombre local de la máquina, ahora imagina que ese mismo servidor lo conectas a una IP púbica, es decir sin dejar de soportar aúnla URL corporativa, cuando WCF le pregunte al IIS el nombre del host le devolera el nombre local.
Cómo solucionarlo, como los profesionales?
Una de las ventajas que tiene haber iniciado mi carrera como profesional de IT antes de ser developer, es que me permite recordar que NO TODO lo debes resolver por código. IIS nos permite configurar los host names para cada sitio.
Vamos a nuestro sitio donde se publico el WCF, clic derecho propiedades, pestaña Web Site y damos clic en el boton advanced.

Damos doble clic sobre el host por defecto y lo editamos, dejando el nombre público correcto de nuestro servidor.

Y eso es todo! ahora las URL de los xsd referenciados desde el wsdl estan direccionadas correctamente.