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