30 noviembre 2012

La programación funcional y los patrones de diseño

Hola a tod@s,
como desarrollador de software creo que todos tenemos que hacer nuestro trabajo lo mejor posible. Una de las herramientas que me han ayudado más en el desarrollo OO ha sido la aplicación de patrones de diseño para solventar problemáticas concretas que se dan de forma recurrente en el desarrollo de sistemas software
“Un patrón de diseño define una posible solución correcta para un problema de diseño dentro de un contexto dado, describiendo las cualidades invariantes de todas las soluciones”
Cómo parte de mi inmersión inicial en el paradigma de programación funcional me pregunte lo siguiente:
  • ¿Tiene sentido hablar de patrones de diseño en el entorno de la programación funcional?
  • ¿Los patrones de diseño clásicos que aplicamos en programación OO (por ejemplo, los patrones GoF) son igualmente válidos para programación funcional?
  • ¿Existe un catálogo de patrones de patrones de diseño específico para programación funcional o se aplican los mismos que aplicamos en programación OO?
Estaba en estas tesituras cuando tropecé con la siguiente reflexión en StackOverflow: Does Functional Programming Replace GoF Design Patterns?, en este hilo de discusión aparecen varias ideas y reflexiones muy interesantes sobre la relación entre la programación funcional y los patrones de diseño. Os recomiendo encarecidamente que lo leáis con atención porqué la discusión es sumamente interesante y algunas de las ideas/opiniones son, cuando menos, sorprendentes para los que venimos del paradigma OO.
En este artículo intentaré enumerar algunas de ellas y, des de la mas absoluta modestia de un neófito en el excitante mundo de la programación funcional, daré mi opinión al respecto.

Patrones de diseño en programación funcional

La discusión inicial del hilo arranca del siguiente parágrafo del artículo Functional Programming For The Rest of Us (otro “must read”!):
“Most people I've met have read the Design Patterns book by the Gang of Four. Any self respecting programmer will tell you that the book is language agnostic and the patterns apply to software engineering in general, regardless of which language you use. This is a noble claim. Unfortunately it is far removed from the truth.
Functional languages are extremely expressive. In a functional language one does not need design patterns because the language is likely so high level, you end up programming in concepts that eliminate design patterns all together.”
el autor argumenta pues que en programación funcional, debido a que se trata de un paradigma en el que se desarrolla y trabaja en un nivel de abstracción más alto que en el paradigma OO, NO tiene sentido aplicar patrones de diseño porqué las capacidades de los lenguajes de programación funcionales los hacen innecesarios.
En este sentido me sorprendió especialmente, que se definiera un patrón de diseño como un “parche” que soluciona un problema o una deficiencia del paradigma o, si somos más específicos, del lenguaje.
Los patrones de diseño evolucionan junto a las capacidades y niveles de abstracción que proporcionan los paradigmas y lenguajes de programación para los que se definen. Un el hilo se pone un ejemplo bastante tonto pero que expresa esta idea:
Supongamos que los lenguajes de programación no proporcionaran una construcción para iterar sobre una colección de elementos, ¿se consideraría una solución que definiera como iterar sobre un conjunto de elementos de una colección un patrón de diseño? Pues posiblemente si, ya que se estaría dando una solución correcta a un problema dado… pero, ¿tiene sentido considerar actualmente esto como un patrón de diseño? No, ya que esta es una capacidad existente en todos los lenguajes de programación y, por tanto, el patrón proporcionaría una solución a un problema inexistente.
Pienso que el nivel de abstracción superior de los lenguajes funcionales hace que, lo que en otros paradigmas era un problema recurrente (i, por tanto, requería un patrón de diseño que proporcionara una solución) simplemente no suponga un problema por qué ya se dispone de una abstracción “de serie” que la soluciona.
¿Quiere decir esto que en programación funcional no tiene sentido hablar de patrones de diseño? para mi no, simplemente los patrones de diseño en programación funcional serán diferentes a los patrones de diseño de otros paradigmas (por ejemplo, los patrones de diseño para programación OO que se define en GoF).

Patrones GoF y la programación funcional

En el hilo se discute bastante sobre si tienen sentido en programación funcional los patrones de diseño definidos en el libro Design Patterns: Elements of Reusable Object-Oriented Software.
Bajo mi punto de vista, la respuesta la tenemos precisamente en el título del libro, concretamente en esta parte: “… of Reusable Object-Oriented Software” => el libro de cabecera sobre patrones de diseño define 23 patrones de diseño bajo un paradigma OO NO bajo un paradigma funcional, lo primordial es que los patrones de diseño lo son para un determinado paradigma, es decir, no son independientes del paradigma bajo el que se aplican. Muchas veces incluso, aunque se promulgue lo contrario, tampoco son independientes del lenguaje de programación que se esté usando.
Sirva como ejemplo el patrón Singleton en un lenguaje “medio OO-medio funcional” como Scala, en el no tiene sentido aplicar este patrón de la forma en que lo describe GoF simplemente porqué el lenguaje tiene soporte directo para ello.
Lo que en programación OO es un problema recurrente que requería un patrón de diseño para su resolución,  en programación funcional simplemente no es un problema, o el problema resulta tan trivial que no requiere la definición de un patrón de diseño para su resolución. El mayor nivel de abstracción y los conceptos presentes en programación funcional como: High Order Functions, Currying, Closures, Data Types algebraicos, Pattern Matching, etc… proporcionan soluciones “de serie” o “embeded” para la mayoría de patrones que describe GoF.
Con los patrones tradicionales en programación funcional pueden pasar tres cosas:
    • el patrón desaparece debido a que el lenguaje ya proporciona esa funcionalidad.
    • el patrón sigue existiendo pero la solución es radicalmente diferente.
    • el patrón sigue existiendo pero la solución se implementa usando nuevas capacidades del lenguaje o del paradigma.
Parece claro pues que NO se requieren los mismos patrones en programación OO que en programación funcional y no es una buena idea intentar aplicar los patrones OO dentro de un paradigma funcional. De hecho la manera de diseñar software en programación funcional es muy diferente a la que estamos acostumbrados en OO, esto hace que los problemas a resolver muchas veces tengan poco a ver con los problemas a los que nos enfrentamos en OO.
Si estáis interesados en saber como se resuelve en programación funcional la problemática que describen los patrones GoF en el enlace Design Patterns in Haskell hay una interesante correspondencia entre estos patrones y su resolución en Haskell y Peter Norvig tiene una presentación con soluciones triviales a 16 de los 23 patrones en lenguajes dinámicos. Hay algunas de estas soluciones que merecen un análisis un poco mas detallado, pero esto lo dejaremos para otras entradas Guio.

Conclusión

Las ideas principales con las que me quedo después de escribir el artículo son:
  • Los patrones de diseño sirven para solucionar problemas existentes, si no hay problema a resolver no tiene sentido hablar de patrón de diseño para resolverlo.
  • La naturaleza de los paradigmas de programación y las capacidades de los lenguajes de programación marcan los patrones de diseño aplicables en cada caso.
  • El mayor nivel de abstracción del paradigma funcional hace que muchos de los problemas que hay en OO no sean problemas y, por tanto, no tenga sentido plantear un patrón de diseño para ellos.
  • En programación funcional se tiende a hablar de reglas o de buenas prácticas para resolver problemas concretos que de patrones de diseño.
  • En programación funcional SI necesitamos patrones de diseño pero son distintos a los que necesitamos en programación OO.
y con la tarea de conocer mucho mas a fondo la programación funcional y los patrones, reglas o buenas prácticas que se aplican en este paradigma.

18 octubre 2012

Programación funcional

Hola a tod@s,
después de mucho tiempo sin escribir nada en el bloc voy a retomar, en la medida de lo posible, la escritura regular de artículos. Últimamente me ha entrado el gusanillo de aprender de que va esto de la programación funcional y para ello he estado haciendo mis primeros pinitos con Scala aprovechando el curso Functional Programming Principles in Scala que imparte el mismísimo Martin Odersky en la plataforma on-line Coursera.
Con el objetivo de afianzar los conocimientos adquiridos en el curso y a modo de recordatorio personal voy a escribir una serie de artículos breves con los conceptos básicos de programación funcional.
Para que no perdáis el tiempo, os comento lo que creo que debéis hacer, en función de vuestro background, si os topáis con un artículo de esta serie:
  • Alguien que no tenga demasiada experiencia en programación funcional pero le interese el tema: no os toméis lo que digo en los artículos “a pies juntillas”, contrastadlo y corregidme las partes que creáis que no son correctas. Tomaros los artículos como un primera toma de contacto y, si os interesa el tema, leed artículos de gente con más experiencia y contrastad lo que se comenta. Después de eso, todo el feedback que podáis aportar a los artículos en forma de comentarios será muy bienvenido. Ah! y apuntaros al curso de programación funcional.
  • Alguien experto en programación funcional: tenéis dos opciones, o bien obviarlos por completo ya que seguro que no os aportarán nada nuevo o bien leer los post con detalle y comentar los posibles errores e inexactitudes que encontréis. Lógicamente os animo a hacer lo segundo!
  • Alguien al quien no le interesa la programación funcional: Obviad los artículos por completo Sonrisa
En esta serie de artículos breves voy a intentar plasmar las dificultades y sorpresas que me encuentro en el proceso de aprendizaje del paradigma de programación funcional (FP) desde la perspectiva de un desarrollador de software OO, que es el paradigma con el que me desenvuelvo bien. El objetivo último es asentar los conocimientos adquiridos sobre programación funcional y hacerlo estableciendo paralelismos con la programación OO.
Para ello voy a resumir los conceptos mas relevantes del curso e intentaré plantear y resolver algunos problemas sencillos de varias formas, usando paradigmas OO, funcionales e híbridos con el propósito de hacer comparaciones y analizar las ventajas y desventajas de cada una de ellas. Para los ejemplos usaré indistintamente Java, C#, JavaScript y Scala.
En el curso se usa Scala como lenguaje de programación pero el verdadero objetivo del curso no es aprender Scala si no aprender a programar siguiendo un paradigma funcional. Pensar la resolución de un problema mediante un paradigma funcional te hace replantear tus esquemas mentales y…, cuesta, para que engañarnos, cuesta mucho. La primera sensación, en la resolución del primer Homework del curso, fue: ¿por donde empiezo? La programación funcional es un paradigma bastante diferente al paradigma usado en programación imperativa y te quedas bastante bloqueado inicialmente!
En esta primera entrada voy a poner en contexto la programación funcional y sus principios básicos, resumiendo partes de la primera semana del curso. También intentaré responder a LA PREGUNTA en mayúsculas, ¿POR QUÉ programación funcional ahora?.

¿Qué es la programación funcional?

Los principales paradigmas de programación existentes son:
  • Programación funcional (FP)
  • Programación imperativa
  • Programación lógica
el paradigma OO lo podemos considerar como un paradigma ortogonal a los tres anteriores ya que se puede combinar con cualquiera de los tres paradigmas anteriores (lo que estamos mas acostumbrados a hacer es a combinar programación imperativa con OO pero veremos que también es posible combinar elementos de FP con elementos OO)
Las ideas principales en las que se basa la programación imperativa son:
  • Modificación de variables mutables usando asignaciones
  • Uso masivo de estructuras de control: bucles, if-then-else, etc…
Las ideas principales en las que se basa la programación funcional son:
  • Se basa en definir teorías para operadores expresadas como funciones
  • Evita, en la medida de lo posible, el uso de mutaciones usando asignaciones (en sentido estricto las prohíbe)
  • Evita, en la medida de lo posible, el uso de estructuras de control (en sentido estricto las prohíbe)
  • Se basa en la abstracción y composición de funciones.
La programación funcional se basa en teorías matemáticas como el lambda-calculus y estas teorías no se pueden aplicar a la programación imperativa ya que su principio básico (la modificación de variables mutables) NO tiene cabida en las teorías matemáticas. Es decir, cuando introducimos la mutación de variables ya no podemos aplicar las leyes por las que se rigen las teorías matemáticas ya que en ellas no está permitida la mutación.
Mi primera sorpresa… ¿en programación funcional no se pude modificar una variable y se deben evitar las estructuras de control? Pues en sentido estricto SI… Es especialmente interesante ver como en el libro Structure and Interpretation of Computer Programs , uno de los libros de clásicos, de cabecera, de la introducción a la programación en los cursos del MIT, no se habla de mutación de variables hasta el capítulo 3…
Pero, ¿porqué es importante usar los conceptos de las teorías matemáticas un un paradigma de programación? Según Odersky sin el uso de teorías matemáticas un paradigma de programación tiene problemas para implementar conceptos de alto nivel y, por tanto, tiene problemas de escalabilidad conceptual. El uso de teorías proporciona formas muy potentes de abstraer y componer funciones y proporciona una escalabilidad conceptual que nos permite dejar atrás la correspondencia uno a uno entre las instrucciones de un lenguaje imperativo y secuencia de instrucciones para una máquina de Von Neumann.
En este punto, después de la primera toma de contacto con la programación funcional, me asaltó una pregunta realmente importante y su análisis me llevo a pensar que la programación funcional tomará mucha relevancia y será clave en el desarrollo de software: ¿Porqué programación funcional?

¿Porqué programación  funcional?

Si hacemos un poco de historia, la programación funcional lleva con nosotros mas de 50 años. Apareció con Lisp a finales de los 50 y, hasta la actualidad, era un paradigma de programación que se usaba casi exclusivamente en el ámbito académico y en algunas aplicaciones de Inteligencia Artificial, su presencia en el mundo de la industria era prácticamente nula. ¿Qué hace pues que ahora parezca que la programación funcional se abre hueco con fuerza en el mundo de la industria?
Para intentar responder a esta pregunta veamos primero las ventajas que nos ofrece la programación funcional. Cuando hablamos de las ventajas de la programación funcional respecto a la programación más clásica aparecen siempre estos argumentos:
  • Alto nivel de abstracción: La programación funcional proporciona un nivel de abstracción mucho más alto.
  • Productividad: Un programa funcional tiene muchas menos líneas de código => menos bugs => menos mantenimiento. En este sentido se argumenta que la programación funcional puede llegar a ser un orden de magnitud más
Si bien los argumentos anteriores son importantes, creo que el porqué de la programación funcional en nuestros días tiene mucho mas que ver con estos dos hechos que con las ventajas comentadas anteriormente:
  • Actualmente las aplicaciones se ejecutan en ordenadores multicore con una capacidad de procesamiento y de paralelización muy grande.
  • Cada vez mas se tiende a desplegar las aplicaciones usando Cloud Computing donde, por temas de escalabilidad, es muy importante que las aplicaciones sean altamente paralelizables.
Estamos pues de acuerdo que la paralelización es un concepto clave para las aplicaciones actuales pero, ¿tiene esto algo que ver con la programación funcional? pues parece que si, y mucho!
En este punto os aconsejo que vais el vídeo O'Reilly OSCON Java 2011: Martin Odersky, "Working Hard to Keep It Simple" que fue el que cambió mi percepción sobre la programación funcional hacia algo mas mundano y realmente necesario. En el vídeo Odersky argumenta que las aplicaciones de hoy son altamente concurrentes por definición y deben ser altamente paralelizables y que esto se puede conseguir más fácilmente siguiendo un paradigma funcional ya que se basa en la inmutabilidad de las variables (bien, realmente promulga el uso de Scala, que estrictamente es un lenguaje híbrido OO-funcional, pero creo que los argumentos que expone se pueden extrapolar a cualquier lenguaje que admita un paradigma funcional).
Del vídeo también encuentro interesante también la asociación que hace entre “programación imperativa = focalización en el tiempo” y “programación funcional => focalización en el espacio” y como lo enlaza con la dificultad de gestionar la concurrencia.
Fijaros que uno de los principios básicos de la pro
Etiquetas de Technorati: ,
gramación funcional es la inmutabilidad de las variables, esto implica que la ejecución del código no tiene “side-effects”, es decir, la ejecución de una función con los mismos argumentos proporciona siempre el mismo resultado => el orden de ejecución de un programa funcional es irrelevante. Ummmm, un código con estas características parece que será altamente parelelizable ¿no?
Para mi esta es la motivación real del auge hoy en día de la programación funcional, ya que soluciona un problema tangible y muy actual como es la paralelización y además lo hace de la mano de un conjunto de teorías muy sólidas (basadas en teorías matemática) y un nivel de abstracción superior a los lenguajes imperativos.

Conclusiones

De mi  primera toma de contacto con la programación funcional me quedo con lo siguiente:
  • La programación funcional se basa en un paradigma muy diferente al que he usado hasta ahora y abre nuevas formas de plantear los problemas mucho mas naturales.
  • La clave del auge actual de la programación funcional es que la escalabilidad y la parelelización son imprescindibles en las aplicaciones actuales y paralelizar con mutación de estado es muy complejo.
  • Quiero aprender mucho más sobre programación funcional!!!

09 septiembre 2011

¿Realmente emerge el diseño con TDD?

Hola a tod@s,

como desarrollador de software cada vez soy más fan de TDD y creo que el “diseño emergente” nos conduce de forma natural a un diseño correcto de nuestras aplicaciones. Hace unos días intentaba explicar las bondades de TDD a unos compañeros y lo hacia con el típico ejemplo de la kata FizzBuzz:

  • caso de prueba con el 3: Red
  • implementación del método para el 3: Green
  • caso de prueba para el 5: Red
  • implementación del  código para el 5: Green
  • refactorización
  • caso de prueba para el 17: Red
  • implementación del  código para el 17: Green
  • refactorización para generalizar y eliminar duplicidades
  • etc…

encuentro que es un ejemplo ideal para explicar como hacer TDD y sus bondades, creo que quedaron convencidos que es una técnica interesante de diseño y no solo una forma de tener test unitarios para poder hacer refactorizaciones sin morir en el intento.

Unos días después estos mismos compañeros estaban leyendo un libro sobre ASP.NET MVC3 y se pusieron a codificar su primer proyecto MVC3 siguiendo el ejemplo y intentando aplicar TDD. En esto que uno de ellos me comento: “Ei, yo ya se que usar dependency injection es una buena decisión de diseño en una aplicación ASP.NET MVC3, pero ¿puedo llegar a esta conclusión mediante un enfoque TDD?” Ostras, la pregunta tiene miga, si la rerformulamos de forma un poco más genérica:

¿nos va a “empujar” TDD a tomar decisiones de diseño “correctas” como el uso de DI o este tipo de decisiones no pueden “emerger” del diseño basado en tests y deben tomarse a priori?

Esta reflexión despertó dos de las preguntas que me hago cada vez que explico/aplico TDD:

  • ¿hasta que punto el diseño “emerge”?
  • ¿hay decisiones de diseño a las que nunca podremos llegar por mucho TDD que hagamos?

el objetivo del post es intentar responder a estas dos cuestiones; para ello me centraré en el ejemplo concreto del uso de DI en una aplicación MVC3 analizando si TDD nos lleva de forma natural a esta decisión, o, por el contrario, TDD nunca nos empujará a tomar una decisión de este tipo.

¿Qué queremos hacer?

La aplicación que usaremos como ejemplo es muy, muy simple: queremos hacer una aplicación ASP.NET MVC3 para mostrar un listado de las películas que hay en cartelera ordenadas por número de espectadores que la han visto. Supongamos que disponemos de un servicio remoto IMoviesService que nos proporciona este listado ordenado y que, al ser un servicio remoto, la consulta de películas puede ser bastante lenta.

Primera iteración: Red, Green, Refactor

Como vamos a desarrollar esta mini aplicación bajo un enfoque TDD lo primero que debemos hacer es crear una prueba para la acción de listado (en esta prueba, para no complicar el ejemplo, simplemente vamos a comprobar que la acción deja en el modelo la colección de películas que devuelve el servicio):

[TestClass]
public class MovieControllerTest
{
    [TestMethod]
    public void ListMoviesPutAllMoviesInModel()
    {
        // Arrange
        var movieController = new MovieController();
        // Act
        var movies = ((IEnumerable<Movie>)movieController.List().Model).ToArray();
        // Verify
        Assert.AreEqual(movies.Length, 5);
        Assert.AreEqual(movies[0].Title, "X-Men");
        Assert.AreEqual(movies[4].Title, "Batman");
    }    
}

Nota: sabemos que el número de películas en cartelera para esta semana es de 5, que hoy la película más vista es “X-Men” y la menos vista “Batman”.


Ejecutamos la prueba y esta ni compila! Red! Evidente, no hemos creado ni el controlador! El siguiente paso es pues crear el controlador y implementar la acción List para que pase la prueba unitaria.

public class MovieController : Controller
{
    public ViewResult List()
    {
        var movieService = new MovieService();
        return View(movieService.AllMovies());
    }   
}

Ejecutamos el test y Bingo! Green!


Refactor: Ya esta ¿no?, nuestro caso de prueba ya pasa  y yo no veo que pueda refactorizar el código por ningún lado… Llegados a este punto podríamos concluir que TDD NO ha hecho emerger la necesidad de usar dependency injection! pero nos olvidamos de algunos detalles importantes:



  • Nuestros tests muy lentos: estamos atacando a la implementación real del servicio y esto es lento.
  • Los tests no son repetibles, dependen del resultado que nos proporcione el servicio. Mañana posiblemente cambie el número de espectadores que han visto las películas y la próxima semana las películas en cartelera.
  • El SUT (Subject Under Test) no es el servicio si no el método List del controller!):



Segunda iteración: introducimos un doble para el servicio


Si queremos que nuestros tests sean rápidos (condición indispensable para que se ejecuten con regularidad) y repetibles tenemos que atacar a un doble del servicio y no a la implementación real. Fijaros que este requerimiento no emerge del proceso normal de TDD (Red, Green, Refactor) ya que los test creados en la primera iteración NO eran correctos.


Necesitamos poder trabajar con dobles des de los test unitarios y con la implementación real cuando se ejecute la aplicación. Tenemos que cambiar el new MovieService() por algo configurable que nos permita usar tanto la implementación real como un doble. La teoría nos dice que podemos hacer esto aplicando un patrón Service Locator (bien sea con una factoría propia o usando un contenedor de IoC), para el ejemplo escogemos la opción de usar una factoría de servicios propia con un método GetService<T> para resolver un servicio y un método RegisterService<T> para registrar servicios (obviamos la creación de esta factoría también lo haríamos siguiendo un enfoque TDD).


Refactorizamos el código de nuestro test para usar la factoría y lo dejamos así:

[TestClass]
public class MovieControllerTest
{
    [TestMethod]
    public void ListMoviesPutAllMoviesInModel()
    {
        // Arrange
        Mock<IMovieService> mock = new Mock<IMovieService>();
        Movie[] movies = new Movie[] 
        {
            new Movie() { Title = "X-Men" },
            new Movie() { Title = "X" },
            new Movie() { Title = "Y" },
            new Movie() { Title = "Z" },
            new Movie() { Title = "Batman" }
        };
        mock.Setup(m => m.AllMovies()).Returns(movies);
        IoCFactory.RegisterService<IMovieService>(mock.Object);
        var movieController = new MovieController();
        // Act
        var movies = ((IEnumerable<Movie>)movieController.List().Model).ToArray();
        // Verify
        Assert.AreEqual(movies.Length, 5);
        Assert.AreEqual(movies[0].Title, "X-Men");
        Assert.AreEqual(movies[4].Title, "Batman");
    }
}

Nota: Usamos Moq para crear un doble del servicio de cartelera, tenéis mas información sobre Moq aquí.


Ejecutamos: Red!


Modificamos el código de la acción List para que obtenga el servicio de nuestra factoría de servicios:

public class MovieController : Controller
{    
    public ViewResult List()
    {
        var movieService = IoCFactory.GetService<IMovieService>();
        return View(movieService.AllMovies());
    }
}

Ejecutamos el test: Green!


Ahora si que ya lo tenemos! Pero tampoco hemos llegado a la necesidad de usar dependency injection! Normalmente nos quedaríamos aquí y no le daríamos mas vueltas pero estamos olvidando la etapa de Refactor! En esta etapa tenemos que refactorizar el código para que, a parte de pasar los test unitarios, nuestro código cumpla los principios de diseño orientado a objetos.


Si analizáis con detenimiento el código generado veréis que no cumple algunos de estos principios:



  • No cumple el principio SOLID de responsabilidad única: El método List tiene dos responsabilidades claras, proporcionar un listado de películas a la vista y gestionar la resolución del servicio mediante la factoría. 
  • Las dependencias de nuestro controlador no están claras, al tener acceso completo a la factoría sus métodos pueden acceder a cualquier objeto que esté registrado en esta.

Nota: otro factor que nos empujaría a refactorizar el código una vez avancemos en el desarrollo es que estaríamos repitiendo la instrucción IoCFactory.GetService<IMovieService>() en todas las acciones del controlador y esto viola el principio DRY. Esto no lo podríamos ver ahora, pero conforme fuéramos implementando acciones se pondría de manifiesto.


Tercera iteración: Necesitamos dependency injection!


Para resolver los problemas anteriores (detectados en la fase de refactoring) tendríamos que poder pasar al controlador la implementación del servicio y usar esa implementación en todas sus acciones, el código de nuestro test debería quedar así:

[TestClass]
public class MovieControllerTest
{
   [TestMethod]
    public void ListMoviesPutAllMoviesInModel()
    {
        // Arrange
        Mock<IMovieService> mock = new Mock<IMovieService>();
        Movie[] movies = new Movie[] 
        {
            new Movie() { Title = "X-Men" },
            new Movie() { Title = "X" },
            new Movie() { Title = "Y" },
            new Movie() { Title = "Z" },
            new Movie() { Title = "Batman" }
        };
        mock.Setup(m => m.AllMovies()).Returns(movies);        
        var movieController = new MovieController(mock.Object);
        // Act
        var movies = ((IEnumerable<Movie>)movieController.List().Model).ToArray();
        // Verify
        Assert.AreEqual(movies.Length, 5);
        Assert.AreEqual(movies[0].Title, "X-Men");
        Assert.AreEqual(movies[4].Title, "Batman");
    }
}

Para hacer este refactoring tenemos que saber que ASP.NET MVC3 nos permite cambiar el resolvedor de dependencias por una implementación propia que use un contenedor de IoC para poder pasar objetos al constructor del controlador y configurar en este contenedor de IoC los servicios que necesitemos. Vemos que el enfoque TDD nos lleva a esto pero debemos tener el conocimiento suficiente de la tecnología con la que trabajamos para ver que la solución es viable.


Nota: Fijaros que como efecto colateral hemos eliminado la necesidad de configurar la factoría de servicios (ni ningún contenedor de IoC) en los test unitarios, creamos el doble en el test y se lo pasamos al controlador!


Ejecutamos: Red!


Modificamos el código del controlador para cambiar el contenedor de IoC por una implementación del servicio y la acción List para que use este servicio:

public class MovieController : Controller
{
    private IMovieService movieService;
    
    public MovieController(IMovieService service)
    {
        this.movieService = service;
    }
    public ViewResult List()
    {        
        return View(this.movieService.AllMovies());
    }
}

Ejecutamos: Green!


Refactor: parece que el código de la acción List no incumple ninguno de los principios de diseño OO y los test se ejecutan correctamente => END!


Conclusión


En esta entrada he intentado explicar mediante un ejemplo concreto una de las dudas que me asaltan con mas frecuencia cuando desarrollo siguiendo un enfoque TDD: ¿hasta que punto TDD nos lleva a hacer “buenos” diseños?


Yo creo que algunas decisiones arquitectónicas de alto nivel se deben tomar inicialmente (por ejemplo, en nuestro caso, el hecho de usar ASP.NET MVC3) pero otras cuestiones de diseño pueden aflorar de una manera mas o menos clara siempre y cuando se cumplan algunas premisas:



  • Conocer las características de un buen test unitario (rápido, repetible, claros, testean solo el SUT, etc…), sin esto nos hubiéramos quedado en la primera iteración y el test hubiera fallado al cabo de un par de días!
  • Alto grado de dominio de la tecnología que estemos usando (en el ejemplo no hubiéramos podido hacer la tercera iteración sin conocer a fondo las capacidades que brinda ASP.NET MVC)
  • Hacer siempre la fase de refactor asumiendo que, a parte de que los casos de prueba pasen, es importantísimo respetar los principios de diseño OO (tampoco hubiéramos llegado el tercer paso sin esto)

Me gustaría saber que opináis al respecto:



  • ¿Creéis que la deducción está muy “cogida con pinzas”?
  • ¿Creéis que la implementación de la acción simple List bajo un enfoque TDD nos lleva de forma natural a deducir que necesitamos DI?
  • ¿Llegaríamos a ella sin tener asumido, a priori, que DI es una buena solución?
  • ¿Dónde está la frontera entre lo que puede aflorar y lo que no?

Saludos, Josep Maria

26 agosto 2011

Javascript no es el demonio (creo)!

Hola a tod@s,

la verdad es que si hace 6 o 7 años alguien me hubiera dicho que estaría escribiendo un post sobre JavaScript que no fuera una crítica salvaje le hubiera tratado de loco. La verdad es que la idea que tenia en mi cabeza sobre JavaScript era la de un lenguaje de scripting para páginas HTML que, básicamente, les servía a los diseñadores gráficos para hacer “guarradas”  sobre el HTML y que convertía la interfaz de usuario en la parte mas oscura, inmantenible y “jodida” de modificar de las aplicaciones web. En la mayoría de aplicaciones acababas con cientos de funciones sueltas, spaggetti code con mucho JavaScript mezclado con el HTML, variables de ámbito global, inexistencia de tests unitarios, reutilización nula o prácticamente nula => Mi máxima siempre había sido: cuanto menos JavaScript tengamos que poner mejor porqué JavaScript = PROBLEMAS!

A todo esto cabe añadir también que nunca he sido muy amante del desarrollo de interfaces gráficas, básicamente por mi prácticamente nula capacidad artística (si, si, ahora ya se que no queda muy bien un título verde sobre un fondo rojo!) y siempre intentaba que fuera el equipo de UI el que lidiara con el JavaScript y enfrentarme a el lo mínimo posible.

A raíz de tener que implementar la UI en un proyecto MVC3 y con el objetivo de conseguir una interfaz agradable y, sobre todo, usable decidí usar JQuery (en MVC3 ya lo tenemos por defecto) para realizar validaciones en cliente, actualizaciones asíncronas de la interfaz y manipulaciones del DOM. Esto combinado con las capacidades de HTML5 y CSS3 (esto último mas para ver una pincelada de las “nuevas” tendencias en interfaces de usuario para aplicaciones web que por necesidad) me permitirían conseguir una UI agradable, potente y actual para mi aplicación web.

La primera decisión pues fue usar JQuery como framework para realizar la validaciones en cliente, gestionar las peticiones AJAX e interactuar con el DOM de las páginas HTML. Primera reflexión: JQuery es un framework de JavaScript => SHIT, me toca lidiar con el dichoso JavaScript!

Llegados a este punto tenia dos opciones:

  • Pasar de puntillas, es decir, coger un manual de JQuery, aprender las capacidades que proporciona para hacer las cuatro cosas que requería mi proyecto, cerrar los ojos e intentar no “enguarrar” demasiado mi UI.
  • Coger el toro por los cuernos y, dado que JQuery es un framework JavaScript, aprender JavaScript para ver si es posible realizar una UI “limpia” y mantenible con él.

Dado que uno de los objetivos del proyecto es experimentar un poco con diferentes tecnologías decidí elegir la segunda opción y darle una oportunidad a JavaScript. 

En el post voy a enumerar las características que me han sorprendido (ya sea para bien o para mal) en esta primera toma de contacto con Mr. JavaScript y introducir brevemente conceptos que nos pueden ayudar a resolver los problemas de los que adolecen muchas UI’s basadas en JavaScript. No esperéis encontrar en él temas avanzados de JavaScript (de hecho el primer título que le había puesto era JavaScript for dummies) ni una guía completa de las diferentes características del lenguaje. La idea del post es que os sirva como índice introductorio, todos los conceptos se presentaran de forma muy concisa (en un párrafo) y, para algunos de ellos, intentaré escribir entradas en el blog para verlos con mas profundidad.

Entre los puntos candidatos a tener, a priori, su propia entrada tenemos:

  • Objetos, funciones, clausuras y ámbitos.
  • Prototipos.
  • Duck typing (#cerveza gratis para @eiximenis por la palabreja).
  • Patrones de diseño.
  • OO clásica frente al enfoque prototípico.
  • Alternativas a la resolución de la herencia clásica en un lenguaje basado en prototipos.
  • Testing, TDD y JavaScript.
  • Proyectos ASP.NET MVC3, ¿cómo gestionamos la parte de JavaScript?.

Si ya conocéis JavaScript y lo usáis de una forma “correcta” posiblemente veáis el post como un refrito de obviedades. En la red hay muchísima literatura sobre JavaScript, muchas de las características las introduciré con una frase y os remitiré a algún enlace para que podáis profundizar en el tema.

Antes de entrar en materia un último apunte: el post esta escrito des del punto de vista de un desarrollador de aplicaciones de servidor acostumbrado a trabajar con lenguajes OO puros fuertemente tipados como Java y C# y con poca experiencia en interfaces de usuario, lenguajes de scripting y lenguajes funcionales.

¿Qué es JavaScript?

Básicamente podemos ver JavaScript cómo un lenguaje de scripting orientado a objetos, basado en prototipos, con funciones como entidades de primera clase y con tipado débil.

A partir de esta definición ya podemos extraer unas pocas conclusiones y abrir bastantes “cajas de pandora!”:

  • JavaScript es un lenguaje orientado a objetos => Debe posibilitar muchas de las características que soportan la mayoría de lenguajes OO: encapsulación, herencia, polimorfismo, etc… Ummmm! Interesante! parece que podremos hacer algo mas que definir conjuntos inconexos de variables globales y funciones!
  • JavaScript es un lenguaje basado en prototipos => En el lenguaje NO existe el concepto de clase sino el de prototipo: pero, perdonad la ignorancia de un triste programador Java/C#, ¿cómo podemos crear objetos con determinados atributos y propiedades sin definir la clase de la que será instancia? pues lo haremos en base al prototipo que todo objeto tiene!  Y este prototipo además nos permitirá hacer herencia por delegación y, por consiguiente, reutilizar código.
  • Las funciones son entidades de primera clase => Vale, bien, ¿y? ¿esto que implica? Pues implica que las funciones se tratan como cualquier otro tipo: se pueden asignar a variables, se pueden pasar como parámetros a métodos, ser devueltos por métodos, etc… ¿Os suena el concepto de puntero a función de C o de delegate en C#? Pues las funciones de JavaScript pueden funcionar de la misma manera. Además, al ser las funciones entidades de primera categoría nos lleva a pensar en JavaScript como un lenguaje candidato a usar una aproximación funcional para el desarrollo. 
  • JavaScript es un lenguaje de tipado débil => Ufff! Ya está, ya se pq no me gustaba JavaScript, lo de poder asignar peras a gatos y que no me avise el compilador de que la pera no puede maullar no me va mucho! Pero, un momento, si desarrollamos usando un enfoque ágil y una metodología orientada al test tendríamos que tener una prueba (fallida por supuesto) en la que le pidiéramos a la pera que maullara… Ummmm otra vez! Igual el hecho de seguir un enfoque dirigido al test hace menos importante las verificaciones de tipos en tiempo de compilación.

Funciones como entidades de primera clase…

El hecho de que las funciones sean entidades de primera clase permite:

  • Asignar funciones a variables.
  • Pasar funciones como argumentos de un método.
  • Devolver funciones como tipo de retorno de un método.
  • Desconectar la definición de la función de su contexto de ejecución y esto, junto con el concepto de clausura, nos ofrecerá unas capacidades importantes.
  • Usar una aproximación de lenguaje funcional al desarrollo.

Ya veremos que el hecho de que las funciones sean entidades de primer nivel nos proporcionará numerosas ventajas y nos permitirá usar una aproximación muy cercana a la programación en lenguajes funcionales aprovechando toda la potencia de estos.

¿Dónde están las variables locales? ¿y la encapsulación, reutilización, mantenibilidad y testabilidad de mi código?

En JavaScript solo tenemos dos ámbitos, el global y el local a una función => toda variable que no esté declarada con la palabra reservada var es global. Esto realmente es una deficiencia del lenguaje ya que nos induce a una mala práctica de programación como son las variables globales (creo que en eso estaremos todos de acuerdo!). Bueno, la primera en la frente! El problema de JavaScript no es que permita el uso de variables globales (casi todos los lenguajes las permiten, public static … en java por ejemplo) sino que JavaScript prácticamente obliga al uso de variables globales. Otro fallo relacionado con las variables globales es que cualquier variable que no se defina con var automáticamente es una variable global (con todos los errores y problemas que esto puede comportar). JavaScript tampoco proporciona ámbito de bloque y esto también nos puede llevar a errores difíciles de detectar.

La parte buena es que, aunque el lenguaje nos empuje a la definición de variables globales, existen técnicas y patrones para minimizar o eliminar el uso de variables globales en nuestros desarrollos, encapsular funcionalidades, ocultar miembros privados y proporcionar una alto grado de reutilización, mantenibilidad y testabilidad de nuestro código JavaScript.

En Techniques, Strategies and Patterns for Structuring JavaScript Code tenéis tres patrones de estructuración de código que os permitirán alcanzar los objetivos anteriores, fijaros como se puede pasar de una aplicación “spaggetti code” a una aplicación bastante estructurada, legible, mantenible y testeable simplemente con la aplicación de uno de los patrones indicados.

¿Y mis clases?

Como ya hemos comentado antes JavaScript es un lenguaje basado en prototipos, en un lenguaje de programación orientado a prototipos NO existen las clases y la herencia se basa en la clonación/copia de objetos existentes y la extensión de sus funcionalidades extendiendo el prototipo del objeto clonado/copiado.

Podéis obtener más información sobre la programación basada en prototipos comparada con la programación tradicional basada en clases en la wikipedia: Programación basada en prototipos y en este artículo de Pedro Cuesta (Universidad de Vigo). Encuentro especialmente interesante la reflexión sobre cómo influye este hecho en el enfoque del modelo de desarrollo que adoptamos, incitando a un desarrollo basado en ejemplos (¿os suena de algo?… metodologías ágiles, TDD, etc…) en vez de crear primero las abstracciones.

Nota: fijaros que el debate entre prototipos y clases es muy antiguo, la mayor parte de referencias son del siglo XX ;-)

Ostras, y puedo añadir comportamiento a los objetos dinámicamente!

Precisamente una de las características presentes en muchos lenguajes de programación basados en prototipos es la capacidad de extender dinámicamente el comportamiento de los objetos en tiempo de ejecución: dado que los objetos se crean por un proceso de copia es fácil modificar en tiempo de ejecución el comportamiento y la estructura de los objetos individuales. JavaScript es un lenguaje dinámico.

Esta muy chulo, si señor! Pero, ¿sirve de algo añadir comportamiento dinámico a nuestros objetos? Bueno pues esto nos lleva a la eterna discusión entre lenguajes dinámicos versus estáticos. No es mi intención posicionarme en este ni en un sentido ni en otro, tenéis mucha literatura en la web, lo que si parece claro es que los lenguajes estáticos cada vez están incorporando mas características de los dinámicos. Por ejemplo, .NET 4.0 incorpora los tipos dinámicos aunque sea básicamente para interoperar con lenguajes dinámicos (tenéis un buen artículo sobre Objetos dinámicos en .NET 4.0: ExpandoObject en el blog de José Manuel Alarcon)

Yo se muchas cosas de OO, ¿las puedo aplicar en JavaScript?

JavaScript es un lenguaje orientado a objetos, y yo estoy harto de trabajar con lenguajes orientados a objeto como Java y C#, entonces debo poder aplicar las buenas prácticas de programación OO en JavaScript, ¿verdad? Bueno pues la respuesta creo que es “si puedes, con un poco de esfuerzo, pero la pregunta realmente interesante es: ¿debo aplicar estas buenas prácticas tal y como lo haría en un lenguaje de programación basado en clases?

Pensad que JavaScript proporciona un modelo de herencia basado en prototipos muy diferente al que proporcionan Java y C# y, posiblemente, se puedan obtener los mismos beneficios pero la forma de hacerlo puede que sea diferente y mucho mas natural para un lenguaje basado en prototipos.

Tenéis un artículo buenísimo, Transitioning from Java Classes to JavaScript Prototypes, donde hay un ejemplo paso a paso de como implementar el patrón Observer en Java y en JavaScript. En él podréis ver que, efectivamente, se puede implementar este patrón tal y como lo haríamos en Java (o en C#) pero que resulta mucho más efectivo y elegante usar una aproximación que se aproveche del hecho que en JavaScript las funciones son entidades de primer nivel.

Oye, lo estas pintando todo muy de color de rosa, ¿es que no hay cosas mal resueltas en JavaScript?

Evidentemente, y bastantes, por enumerar solo algunas:

  • Dependencia de las variables de ámbito global.
  • Inexistencia del ámbito de bloque.
  • Sintaxis muy enrevesada para hacer cosas muy simples (leed JavaScript is Dead. Long Live JavaScript! para ver algunas de las propuestas de mejora de la sintaxis).
  • Uso del operador + tanto para añadir como para concatenar.
  • with y eval.
  • false, null, undefined, NaN.
  • etc…

Entonces, ¿recomiendas el uso de JavaScript?

En este post solo hemos visto unas breves pinceladas de JavaScript y con esto no podemos evaluar si es una buena opción o no, dependerá de mil factores: tipo de proyecto, tecnologías, alcance, equipo, etc…

Hay un hecho importante a tener muy en cuenta y que ha sido el que me ha hecho decantar por el uso de JavaScript en mi proyecto:  es la única opción si queremos programación en cliente para las aplicaciones web! Si os encontráis en este caso y tenéis que usarlo lo que si os recomiendo es que invirtáis algo de tiempo en entender la idiosincrasia del lenguaje e intentéis adaptaros a esta en vez de intentar que el lenguaje se adapte a vuestra manera de trabajar.

JavaScript tiene cosas malas pero también muchas cosas buenas, evitad las malas prácticas y centraros en aprovechar las bondades del lenguaje, que, aunque a estas alturas todavía me estén sorprendiendo, son bastantes. Y, sobre todo, intentad conocerlo antes de usarlo (como dice Douglas Crockford, JavaScript es de los pocos lenguajes que la gente cree que puede usar sin haberlo estudiado)!

Bien y con esta última recomendación lo dejamos por hoy, espero haberos abierto el apetito (o no haberos aburrido en exceso) y que leáis los siguientes artículos donde intentaré profundizar un poco más en algunos de estos temas. Podéis dejar cualquier sugerencia sobre temas de los que os gustaría hablar en los comentarios del post.

Saludos a tod@s! Josep Maria

Otras referencias

08 agosto 2011

Dependency Injection en aplicaciones N-Layer

Hola a tod@s,

Hace unos días publique un post publiqué un post sobre como realizar IoC usando DI o bien usando SL, en este post llegamos a la conclusión que es mucho mas efectivo hacer DI para conseguir IoC. Yo me quede convencido que IoC es una buena opción para mis proyectos y que DI era la mejor alternativa pero NO vimos como implementarlo, en este post vamos a bajar a las trincheras y veremos como podemos hacer IoC usando DI en una aplicación N-Layer de forma práctica.

Para ello imaginemos que queremos hacer una aplicación multicapa con la siguiente arquitectura:

Architecture

  • La aplicación simplemente publica un servicio que, dado un nombre, nos devuelve un saludo. Por ejemplo, si le pasamos “josep maria” el servicio nos devolverá “Hola Josep Maria!”
  • La aplicación se divide en 4 capas, presentación, servicios distribuidos, aplicación y dominio.
  • En la capa de presentación tenemos un cliente web y una aplicación WCF que van a consumir el servicio de la capa de aplicación Greeting.
  • La capa de servicios distribuidos expone mediante WCF el servicio Greeting de la capa de aplicación para que este pueda ser consumido por clientes remotos.
  • La capa de aplicación expone un servicio Greeting que, simplemente, devuelve un saludo personalizado al usuario. El servicio Greeting de la capa de aplicación usa un servicio de la capa de dominio (Capitalize) para poner en mayúsculas las primeras letras del nombre del usuario.
  • Los clientes web acceden directamente al servicio Greeting de la capa de aplicación.
  • Los clientes WCF acceden a una adaptador del servicio Greeting en la capa de servicios distribuidos.

La aplicación en si es una chorrada y, como veis, esta un poco/un mucho “sobrearquitecturada” (¿solo un poco? Vaya tela de tio!) Su pretensión es hacer una prueba de concepto para mostrar como se pueden inyectar los servicios de aplicación y/o de dominio a los controladores de la capa de presentación MVC y a los servicios distribuidos WCF sin hacer muchas cosas raras, dejando que sea la infraestructura de MVC y de WCF la que inyecte estos servicios. Los principios que aplicamos a esta aplicación “chorra” se pueden extrapolar a cualquier aplicación N-Layer compleja donde seguro que tendrán mucho mas sentido.

Como la literatura no es lo mi fuerte os pongo el código que queremos que tenga nuestra aplicación en cada una de las capas:

Capa de presentación:

Slide2

Capa de servicios distribuidos:

Slide3

Capa de servicios de aplicación:

Slide4

Capa de servicios del dominio

Slide5

Resumiendo, lo que queremos lograr es:

  • Conseguir IoC por medio de DI con inyección de dependencias en el constructor en toda la aplicación.
  • Registrar los dos servicios (Greeting y Capitalize) en un contenedor de IoC (Unity en nuestro caso) des de un único punto para toda la aplicación.
  • Conseguir que la capa de presentación web, implementada mediante ASP.NET MVC3, use Unity como contendor de IoC para resolver las dependencias. Definir una dependencia en el constructor del controlador web al servicio Greeting de la capa de aplicación (que a su vez tiene otra dependencia con el servicio Capitalize de la capa de dominio) y que sea la infraestructura de MVC la que las resuelva.
  • Conseguir que la capa de servicios remotos, implementada mediante WCF, use Unity como contendor de IoC para resolver las dependencias. Definir una dependencia en el constructor del servicio remoto al servicio Greeting de la capa de aplicación (que a su vez tiene otra dependencia con el servicio Capitalize de la capa de dominio) y que sea la infraestructura de WCF la que las resuelva.
  • No hacer ningún Resolve explícito des de la aplicación.

Dependency injection en la capa de presentación con ASP.NET MVC 3

El código del controlador que queremos evitar seria similar a este:

    public class HomeController : Controller
    {
        private IGreetingService greetingService;
        
        public HomeController(IUnityContainer container)
        {
            this.greetingService = container.Resolve<IGreetingService>();
        }
        
        public ActionResult Index()
        {
            ViewBag.Message = greetingService.SayHello(Request.Params["name"]);
            return View();
        }        
    }


fijaros que con este código estaríamos haciendo IoC pero mediante SL y no mediante DI (consultad el post para ver porqué se prefiere el uso de DI al uso de SL).



Afortunadamente ASP.NET MVC3 está muy preparado para usar un contendor de IoC para resolver las dependencias, y hay mucha información en la red explicando paso a paso como hacer-lo. Básicamente y de forma resumida, los pasos a realizar serian los siguientes:





  1. Crear nuestro UnityDependencyResolver que utilice Unity para resolver los tipos extendiendo de IDependencyResolver.

  2. Crear el contenedor de Unity.

  3. Registrar todos los controladores de la aplicación en este contenedor.

  4. Registrar todos los tipos que deba resolver la aplicación en este contenedor.

  5. Indicar a MVC3 que use nuestro UnityDependencyResolver para resolver todas las dependencias.


Podemos hacer estos pasos manualmente pero en el ejemplo me he decantado por usar el package Unity.Mvc3 de Paul Hiles que ya nos proporciona muchas de estas tareas:





  • Nos proporciona una extensión de Unity para registrar todos los controllers de la aplicación en el contenedor de IoC.

  • Añade una clase Bootstrapper al proyecto web que se encarga de crear el contenedor de Unity, registrar los controladores (mediante la extensión), configurar Unity como dependency resolver de MVC y registrar los tipos de nuestra aplicación. Esta clase Bootstrapper se llama des de Application_Start() del Global.asax


el código de la clase Bootstrapper generada por Unity.Mvc3 tiene el siguiente aspecto:

    public static class Bootstrapper
    {
        public static void Initialise()
        {
            var container = BuildUnityContainer();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }
        private static IUnityContainer BuildUnityContainer()
        {
            IUnityContainer container = new UnityContainer();           
            container.RegisterControllers();
            IoCComponentsRegistration.RegisterApplicationTypes(container);
            
            return container;
        }
    }


para hacer la configuración del proyecto MVC3 usando esta librería hemos seguido los pasos descritos en Integrating The Unity.Mvc3 1.1 NuGet Package From Scratch con la única salvedad que hacemos el registro de nuestros tipos en el método estático IoCComponentsRegistration.RegisterApplicationTypes en una librería de clases independiente y no en el Bootstrapper directamente, con esto conseguimos centralizar este registro de tipos y no tener dependencias en nuestro proyecto MVC con todos los proyectos de la aplicación:

    public class IoCComponentsRegistration
    {
        public static void RegisterApplicationTypes(IUnityContainer container)
        {
            container.RegisterType<IGreetingService, GreetingService>();
            container.RegisterType<ICapitalizeService, CapitalizeService>();
        }
    }


Nuestro controlador quedará así:

    public class HomeController : Controller
    {
        private IGreetingService greetingService;
        
        public HomeController(IGreetingService service)
        {
            this.greetingService = service;
        }
        
        public ActionResult Index()
        {
            ViewBag.Message = greetingService.SayHello(Request.Params["name"]);
            return View();
        }        
    }


con esto ya tenemos Unity configurado y listo para resolver todas la dependencias de la aplicación! Fijaros que se están resolviendo todas las dependencias con Unity, DI y inyección de dependencias en el constructor que es el objetivo que perseguimos.



Nota: Unity.Mvc3 también proporciona un Dependency Resolver de Unity para registrar los tipos que implementan IDisposable (por ejemplo los contextos de Entity Framework), tenéis más información en Introducing The Unity.Mvc3 NuGet Package To Reconcile MVC3, Unity and IDisposable.



Dependency injection en la capa de servicios remotos con WCF



Igual que para el caso de los controladores de la capa web, el código del servicio remoto que queremos evitar es este:

    public class GreetingService : IGreetingService
    {
        private ApplicationServices.IGreetingService greeting;
        public GreetingService(IUnityContainer container)
        {
            this.greeting = container.Resolve<IGreetingService>();
        }
        public string SayHello(string name)
        {
            return this.greeting.SayHello(name);
        }
    }


ya que con este código estaríamos usando SL y no DI. Para hacerlo vamos a usar los puntos de extensión que nos proporciona WCF.



Primero tenemos que definir un proveedor de instancias que utilice Unity para resolver los tipos. Para esto creamos una clase que implementa la interfaz IInstanceProvider de WCF y que devolverá las instancias configuradas en Unity cuando WCF necesite resolver un tipo:

    public class UnityInstanceProvider : IInstanceProvider
    {
        private readonly Type serviceType;
        private IUnityContainer container;
        public UnityInstanceProvider(Type serviceType)
        {
            this.serviceType = serviceType;
            this.container = new UnityContainer();
            IoCComponentsRegistration.RegisterApplicationTypes(container);
        }
        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            return this.container.Resolve(serviceType);
        }
        public object GetInstance(InstanceContext instanceContext)
        {
            return this.GetInstance(instanceContext, null);
        }
        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {
            this.container.Teardown(instance);            
        }
    }


Fijaros que estamos llamando al mismo método (IoCComponentsRegistration.RegisterApplicationTypes) que en el caso de la capa de presentación para registrar las instancias en el contenedor de Unity!



Una vez hecho esto debemos configurar WCF para que use nuestro proveedor de instancias en vez del proveedor de instancias por defecto, para ello crearemos un nuevo “comportamiento” (service behavior) para nuestros servicios implementando la interfaz IServiceBehavior de WCF:

    public class UnityServiceBehavior : Attribute, IServiceBehavior
    {
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (var item in serviceHostBase.ChannelDispatchers)
            {
                var dispatcher = item as ChannelDispatcher;
                if (dispatcher != null) 
                {
                    dispatcher.Endpoints.ToList().ForEach(endpoint =>
                    {
                        endpoint.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(serviceDescription.ServiceType);
                    });
                }
            }
        }
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
        }
       
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {            
        }        
    }
}


Básicamente este comportamiento insta a WCF a usar nuestro proveedor de instancias para todos los Endpoints de todos los canales.



Una vez hecho esto tenemos que asociar este comportamiento nuestro servicio distribuido, esto lo podemos hacer mediante atributos, mediante un host de servicio propio o mediante configuración. Si lo hacemos mediante atributos debemos crear la clase que implementa el servicio distribuido decorada con el atributo [UnityServiceBehavior], la implementación del servicio WCF queda así:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    [UnityServiceBehavior]
    public class GreetingService : IGreetingService
    {
        private ApplicationServices.IGreetingService greeting;
        public GreetingService(ApplicationServices.IGreetingService greeting)
        {
            this.greeting = greeting;
        }
        public string SayHello(string name)
        {
            return this.greeting.SayHello(name);
        }
    }


Lo último que nos queda es crear un host propio que registre el comportamiento definido al hacer un Open:

    public class UnityServiceHost : ServiceHost
    {        
        public UnityServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
        }
        protected override void OnOpening()
        {
            base.OnOpening();
            if (this.Description.Behaviors.Find<UnityServiceBehavior>() == null)
            {
                Description.Behaviors.Add(new UnityServiceBehavior());
            }            
        }
    }


crear la factoría de hosts que nos devolverá la instancia de host del tipo UnityServiceHost:

    public class UnityServiceHostFactory : ServiceHostFactory
    {
        public ServiceHost CreateServiceHost(Type serviceType, string baseAddress)
        {
            return CreateServiceHost(serviceType, new[] { new Uri(baseAddress) });
        }
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            return new UnityServiceHost(serviceType, baseAddresses);
        }
    }


y configurar el servicio remoto Greeting para que use esta factoría de hosts:

<%@ ServiceHost Language="C#" 
Debug="true" Service="DistributedServices.GreetingService" CodeBehind="GreetingService.svc.cs" 
Factory="DistributedServices.UnityServiceHostFactory"
%>


y listos, nuestra capa de servicios WCF estará usando Unity para resolver todas las dependencias!



Fijaros, por último, que también aquí se están resolviendo todas las dependencias con Unity, DI y inyección de dependencias en el constructor: el servicio Greeting de la capa de aplicación tiene una dependencia con el servicio Capitalize de la capa de dominio.



Nota: esta solución se basa en el post Integrating StructureMap with WCF de Jimmy Bogard adaptado al caso en que usemos Unity como contenedor de IoC. En el blog de Johan Danforth también tenéis una entrada interesante que explica como hacer test unitarios de vuestros servicios WCF usando Unity: Integration Testing WCF Services with Unity



Resumen



En el post hemos visto una prueba de concepto para hacer IoC mediante DI y inyección de dependencias en el constructor en aplicaciones que sigan una arquitectura N-Layer. Es importante notar que solo realizamos la configuración del contenedor de IoC en los puntos de entrada de la aplicación: los servicios distribuidos y la aplicación web y dejamos a la infraestructura de MVC y WCF la responsabilidad de resolver las dependencias => NO accedemos al contenedor de IoC en ningún punto de la aplicación.



Saludos, Josep Maria