Archive for July 30, 2010

Writing a Windsor Service Locator adapter for ASP.NET MVC3 Preview 1

A few days ago Scott Guthrie announced the ASP.NET MVC 3 Preview 1 availability. The team did such a great job adding Dependency Injection to the whole framework using a slightly modified Service Locator, in that way you may plug your favorite DI container. As you may imagine, there is no DI container shipped with this first preview, so you need to roll your own. Brad Wilson did such a terrific job writing a post series about DI using MVC 3 Preview 1 and create a Unity Container Service Locator adapter, I really recommend you read his blog post series before continue with this post :)

I prefer Castle Windsor Container, so using his blog posts as a blueprint, I write a simple Service Locator adapter for Castle Windsor.

Let’s tart with the Controller Factory:

using System.Web.Mvc;
using System.Web.Routing;
using Castle.MicroKernel;

namespace Castle.Windsor.Mvc {
    public class WindsorControllerFactory : IControllerFactory {
        private readonly IControllerFactory _defaultFactory;
        private readonly IWindsorContainer _container;

        public WindsorControllerFactory(IWindsorContainer container) : this(container, new DefaultControllerFactory()) {
            _container = container;
        }

        public WindsorControllerFactory(IWindsorContainer container, IControllerFactory defaultFactory) {
            _container = container;
            _defaultFactory = defaultFactory;
        }

        public IController CreateController(RequestContext requestContext, string controllerName) {
            try {
                return _container.Resolve<IController>(controllerName.ToLowerInvariant());
            } catch (ComponentNotFoundException) {
                return _defaultFactory.CreateController(requestContext, controllerName);
            }
        }

        public void ReleaseController(IController controller) {
            _container.Release(controller);
        }
    }
}

Pretty straighforward, now, it’s time for the Castle Windsor adapter for MvcServiceLocator, it is almost a wrap over Windsor methods:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Web.Mvc;

namespace Castle.Windsor.Mvc {
    public class WindsorMvcServiceLocator : IMvcServiceLocator {
        private readonly IWindsorContainer _container;

        public WindsorMvcServiceLocator(IWindsorContainer container) {
            _container = container;
        }

        public object GetService(Type serviceType) {
            return _container.Resolve(serviceType);
        }

        public IEnumerable<TService> GetAllInstances<TService>() {
            return _container.ResolveAll<TService>();
        }

        public IEnumerable<object> GetAllInstances(Type serviceType) {
            return _container.ResolveAll(serviceType).Cast<object>();
        }

        public TService GetInstance<TService>() {
            return _container.Resolve<TService>();
        }

        public TService GetInstance<TService>(string key) {
            return _container.Resolve<TService>(key);
        }

        public object GetInstance(Type serviceType) {
            return GetService(serviceType);
        }

        public object GetInstance(Type serviceType, string key) {
            return _container.Resolve(key, serviceType);
        }

        public void Release(object instance) {
            _container.Release(instance);
        }
    }
}

To allow inject filters you need to provide a IFilterProvider implementation, I did it using Brad’s post about DI on Action Filters:

using System.Web.Mvc;

namespace Castle.Windsor.Mvc {
    public class WindsorFilterAttributeFilterProvider : FilterAttributeFilterProvider {
        private readonly IWindsorContainer _container;

        public WindsorFilterAttributeFilterProvider(IWindsorContainer container) {
            _container = container;
        }

        protected override System.Collections.Generic.IEnumerable<FilterAttribute> GetControllerAttributes(
            ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
            var attributes = base.GetControllerAttributes(controllerContext, actionDescriptor);
            foreach (var attribute in attributes) {
                _container.BuildUp(attribute.GetType(), attribute);
            }

            return attributes;
        }

        protected override System.Collections.Generic.IEnumerable<FilterAttribute> GetActionAttributes(
            ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
            var attributes = base.GetActionAttributes(controllerContext, actionDescriptor);
            foreach (var attribute in attributes) {
                _container.BuildUp(attribute.GetType(), attribute);
            }

            return attributes;
        }
    }
}

That last part was a little different than others mainly because we cannot use constructor injection in Attributes, so an easy way is just to create a simple method extension to extend Windsor and inject the properties in an already created instance:


using System;
using System.Linq;

namespace Castle.Windsor.Mvc {
    public static class WindsorExt {
        public static void BuildUp(this IWindsorContainer container, Type type, object instance) {
            var properties = type.GetProperties().Where(p => p.CanWrite && p.PropertyType.IsPublic);
            foreach (var propertyInfo in properties) {
                if (container.Kernel.HasComponent(propertyInfo.PropertyType)) {
                    propertyInfo.SetValue(instance, container.Resolve(propertyInfo.PropertyType), null);
                }
            }
        }
    }
}

Simple… you can grab the sourcecode from my bitbucket repository http://bitbucket.org/cprieto/castle-windsor-mvc

NOTE: before anybody else start screaming about using Service Locator: I don’t like at all the use of Service Locator, and I think it must be considered the atomic bomb in component injection (it’s even considered an antipattern as Mark Seeman describes). I’m writing this articule to sample how to to plug your own DI framework inside ASP.NET MVC 3 Preview 1… at least we have now a native way to do it.

VAN ASP.NET MVC3 y Razor en Alt.Net Hispano

Hoy tube el placer de compartir con mis camaradas “alt.netters” de Alt.Net Hispano en la VAN titulada “Webmatrix, Razor, MVC3 y otras hierbas”. Interesante la discusión y comentarios post VAN. Pronto publicaran los videos de la VAN para verlos offline, mientras tanto los dejo con las diapositivas :)

Diapositiva en Slideshare.net

NOTA: El código de mi ejemplo de Windsor Service Locator para MVC 3 pueden encontrarlo en mi cuenta de Bitbucket http://bitbucket.org/cprieto/castle-windsor-mvc

PHP y Microsoft como plataforma

Hace unas semanas fui invitado por parte de Microsoft a conversar un poco en el DrupalCamp 2010 que se realizó en Guatemala, quizás muchos no lo saben pero en “una vida pasada” fui developer en PHP por mucho tiempo (ufff… tiempos aquellos). Bien, fue interesante regresar a hablar sobre el soporte en que ahora ha trabajado Microsoft en su “stack” junto con PHP, transformando a Microsoft Windows no solamente en una excelente plataforma de desarrollo para PHP, sino también en una fuerte plataforma de ejecución.

Como lo había prometido (pero un poco tarde esta vez) los dejo con las diapositivas de la charla, quizás algún otro día conversamos un poco más sobre PHP (si me diera tiempo claro).

Ver diapositiva en Slideshare.net

Contribuyendo al proyecto Vale, ¿por dónde comienzo?

Como muchos recordaran, por iniciativa de los líderes de Alt.Net hispano se comenzó un proyecto desde cero, el proyecto Vale, una plataforma de validación que muestra y pretende enseñar la mística de como contribuir a proyectos OSS y usar Test Driven Development como herramienta de diseño y uso. Algo que suele preguntarme la gente es “quiero contribuir y aprender pero… ¿y por dónde comienzo?" bien, a manera de ejemplo decidí crear un pequeño screencast sobre como contribuir con una feature nueva al proyecto, desde su concepción hasta enviar nuestros cambios al repositorio. Es mi primer “screencast”, así que con gusto escucho sugerencias :)

Contribuyendo al proyecto Vale from Cristian Prieto on Vimeo.

Lanzamiento de Visual Studio 2010 en la comunidad

Hace poco más de una semana se llevó a cabo el lanzamiento comunitario de Visual Studio 2010 en la Ciudad de Guatemala, junto con compañeros como Carlos Lone (Microsoft Client Application Development MVP) y Manolo Herrera (Microsoft Sharepoint MVP) tube el honor de presentar las nuevas características y ventajas de esta nueva versión de ASP.NET 4.0 y Visual Studio 2010.

Como alguno siempre me pide las diapositivas de la presentación, se las dejo para que puedan descargarlas (en Slideshare).

Ver diapositiva en Slideshare.net

¡Saludos!