IDisposable Thoughts

Honey… where is my coding t-shirt?

Hey there! Thanks for dropping by Theme Preview! Take a look around
and grab the RSS feed to stay updated. See you around!

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.

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 :)

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).

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).

¡Saludos!

.NET y Configuraciones – Parte 8

La última vez que conversamos acerca de configuraciones sacamos a relucir lo sencillo que es agregar soporte para funciones de validación callback, y antes de eso comentábamos lo sencillo que era agregar soporte para validación de forma declarativa usando los atributos de validación incluídos en la Configuration Framework de la .Net Framework.

Hoy seguiremos caminando en el soporte de validación customizada de secciones y elementos de validación, pero esta vez creando nuestros propios atributos de validación customizados.

Atributos de Validación

Un atributo de validación nos permite validar los elementos o secciones de nuestra configuración de .Net, simplemente tenemos que adornar ese elemento con el atributo en cuestión. La .Net framework nos incluye algunos atributos ya dentro de la caja, pero podemos agregar los nuestros propios de forma sencilla.

Realmente un atributo de validación costa de dos clases: La clase que marca el atributo (un atributo marcador) y la clase que ejecuta la acción de validar (el validador). Como podremos notar en este lado de la framework se utilizan los atributos de una manera muy particular (y que en lo personal me gusta) de mezclar el atributo como marcador pero no como ejecutor.

Usemos un simple ejemplo, imaginemos que necesitamos validar la entrada de correos electrónicos, como todos sabemos, podemos seguir un par de reglas expuestas en una serie de RFC’s acerca de direcciones de email. Bueno, comencemos por la clase que hace realmente la validación, esta debe heredar de la clase ConfigurationValidatorBase y luego el override de los métodos CanValidate (que nos dice si podemos o no validar el tipo en cuestión) y Validate (quien realmente realiza la validación).

using System;
using System.Configuration;
using System.Text.RegularExpressions;

namespace Cprieto.Samples {
    public class EmailValidator : ConfigurationValidatorBase {
        private const string Word = "[^\\x00-\\x1F^\\(^\\)^\\<^\\>^\\@^\\,^\\;^\\:^\\\\^\\\"^\\.^\\[^\\]^\\s]";
        private const string IpEntry = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";
        private static readonly string Domain = string.Format("({0}+(\\.{0}+)*", Word);

        private static readonly Regex EmailRegex =
            new Regex(string.Format("^{0}+(\\.+)*@{1}|{2})$", Word, Domain, IpEntry), RegexOptions.Compiled);

        public override bool CanValidate(Type type) {
            return type == typeof (string);
        }

        public override void Validate(object value) {
            var item = (string) value;
            if (!string.IsNullOrEmpty(item) && !EmailRegex.IsMatch(item))
                throw new ArgumentException("value is not a valid email");
        }
    }
}

Bien, ahora simplemente creamos el atributo marcador, este debe heredar de ConfigurationValidatorAttribute y la parte importante de este es el override de la propiedad ValidatorInstance que retorna una nueva instancia de nuestra clase validadora.

using System.Configuration;

namespace Cprieto.Samples {
    public class EmailValidatorAttribute : ConfigurationValidatorAttribute {
        public override ConfigurationValidatorBase ValidatorInstance {
            get { return new EmailValidator(); }
        }
    }
}

Ahora simplemente lo aplicamos a nuestra sección de configuración:

using System.Configuration;

namespace Cprieto.Samples {
    public class SampleConfigurationSection : ConfigurationSection {
        [CallbackValidator(Type = typeof(PortValidator),
            CallbackMethodName = "Validate")]
        [ConfigurationProperty("port", DefaultValue = 80)]
        public int Port {
            get { return (int) this["port"]; }
        }

        [ConfigurationProperty("host", IsRequired = true)]
        public string Host {
            get { return (string) this["host"]; }
        }

        [EmailValidator]
        [ConfigurationProperty("email")]
        public string Email {
            get { return (string) this["email"]; }
        }
    }
}

Y claro, nunca cae de más un pequeño archivo de validación que debe marcar como inválido

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="sample"
             type="Cprieto.Samples.SampleConfigurationSection, Cprieto.Samples.ValidationCallback"/>
  </configSections>
  <sample port="80" host="localhost" email="invalid@@email" />
</configuration>

Bueno, y ahora me queda pensar que escribo para el siguiente post de la serie :) Hasta la próxima!

Cambiando el usuario de un commit en Mercurial

Hoy mi gran amigo José Romaniello (@jfroma) me abarcó con una pregunta acerca de Mercurial un poco curiosa pero bastante bien fundada:

Por un error anterior, necesito cambiar el nombre de usuario que aparece registrado en algunos commits de mi repositorio de Mercurial por otro usuario, cómo puedo hacerlo? ¿tengo que reescribir la historia del repositorio?

Digamos que al principio de mis commits utilizaba el nombre de Santa Clos (digamos que así estaba la máquina con que comencé a trabajar el proyecto) y luego decidí cambiar el nombre a mi correcto nombre de Cristian Prieto, bueno, si vemos el log de commits tendremos algo como lo siguiente:

Powershell-2010-07-06_19.20.15

Bueno, si quieren pueden intentar cambiar la historia con Hg mq, pero una manera mucho más sencilla si tienen su historial local es usar a nuestro amigo “Convert”.

Algunos creen que convert (la cual es una extensión de Mercurial incluida en la instalación) simplemente sirve para convertir de un sistema de control de versiones a otro (entiéndase de Subversion a Mercurial, como nos lo muestra nuestro amigo Fabio), la verdad también nos permite convertir de un repositorio de Mercurial a otro, y en el transcurso de la conversión cambiar los valores de cada uno de los commits, entre ellos, el author del commit. En este caso en particular basta con crear un archivo “authors” que contenga la lista de valores de conversión de los autores, es un simple archivo de texto con retorno de carro. En este caso tendremos un archivo con este simple contenido:

Santa Clos <santa@northpole.net>=Cristian Prieto <me@cprieto.com>

Ahora asegurémonos que tenemos nuestra extensión convert activada, revisen que en su Mercurial.ini tengan la siguiente línea

[extensions]
hgext.convert=

Y basta solamente convertir nuestros repositorios

hg convert --authors authors.txt orig changed

Bien, ahora si revisamos el historial nos quedaría bello, como esperábamos :)

Powershell-2010-07-06_19.28.20

Para saber un poco más acerca de convert, basta con la página del wiki de Mercurial :)

.NET y Configuraciones – Parte 7

Bueno, luego de un largo tiempo de ausencia creo que es hora de continuar con la serie acerca de configuraciones en la .NET Framework. La última vez que conversamos mencionamos la capacidad que tenía una sección de configuración de validar los elementos de configuración, esta capacidad es netamente declarativa a partir de atributos que indican el tipo de validación que debe llevarse a cabo. Como ustedes podrán imaginarse existirán situaciones donde es necesario realizar validaciones afuera de las que ya nos trae la configuration framework.

Existen dos formas de especificar o crear nuestras propias rutinas de validación de la configuración: mediante validation callback y utilizando custom validation attributes. Veremos ambas en esta serie y comenzaremos con la primera: validation callbacks

Validation Callbacks

Imaginemos el siguiente caso hipotético, nuestra sección de validación requiere que se ingrese el nombre o host de la aplicación y el puerto para ese host, la sección en cuestión se vería algo así:

using System.Configuration;

namespace Cprieto.Samples {
    public class SampleConfigurationSection : ConfigurationSection {
        [ConfigurationProperty("port", DefaultValue = 80)]
        public int Port {
            get { return (int) this["port"]; }
        }

        [ConfigurationProperty("host", IsRequired = true)]
        public string Host {
            get { return (string) this["host"]; }
        }
    }
}

Bien, ahora imaginemos que por alguna razón especial el puerto no debe ser ni el 110 ni el 23 (o podría ser cualquier otra regla que a uno se le ocurra). Una forma sencilla de realizar esta validación es usando un método callback, la idea es sencilla, cuando la framework obtenga el valor ejecutará el método o callback de validación pasando ese valor (o el por defecto) como parámetro, dentro del método (o callback en este caso) si no se cumple el requerimiento o validación, se arroja una ArgumentException. Los requerimientos del callback method son sencillos: Debe ser público, estático, ser de tipo void (o una Sub en Visual Basic) y tener un parámetro tipo Object (que recibe el valor a validar). Nuestra simple callback de ejemplo sería algo así:

using System;

namespace Cprieto.Samples {
    public class PortValidator {
        public static void Validate(object value) {
            var num = Convert.ToInt32(value);
            if (num == 110 || num == 23)
                throw new ArgumentException("port must not be 110 or 23");
        }
    }
}

Ahora simplemente le decimos declarativamente a la sección de configuración que use ese callback basta con adornar el elemento con el atributo CallbackValidatorAttribute

using System.Configuration;

namespace Cprieto.Samples {
    public class SampleConfigurationSection : ConfigurationSection {
        [CallbackValidator(Type = typeof(PortValidator), CallbackMethodName = "Validate")]
        [ConfigurationProperty("port", DefaultValue = 80)]
        public int Port {
            get { return (int) this["port"]; }
        }

        [ConfigurationProperty("host", IsRequired = true)]
        public string Host {
            get { return (string) this["host"]; }
        }
    }
}

Es importante que recordemos pasar el tipo del validador (o sea, la clase que lo contiene) y el nombre de la función de callback

Para probar nuestro validador basta con usar el siguiente app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="sample"
             type="Cprieto.Samples.SampleConfigurationSection, Cprieto.Samples.ValidationCallback"/>
  </configSections>
  <sample port="110" host="localhost" />
</configuration>

Bien, como dijo Porky… los dejo hasta la siguiente entrega donde continuaremos hablando de validadores en las configuraciones de la .Net Framework, Saludos miles a todos :)

Como ustedes habrán notado la comunidad ha estado en un estado de "pausa" por los últimos meses. Para aprovechar el momentum hemos estado organizando un evento de lanzamiento para Visual Studio 2010 a nivel comunitario. Los dejo con la información :)

Lugar: Oficinas de Microsoft, Edificio Torre Citibank (Intercontinental) [3a Avenida 13-78 Zona 10, Of 1101, Guatemala]

Fechas: Miércoles 23, Jueves 24, Viernes 25 de Julio

Horas: de 6pm a 9pm

Expositores y temas

Silverlight/WPF 4.0 Development

Expositor: Carlos Lone, Microsoft MVP Client Application Development, http://weblogs.asp.net/carloslone/

Fecha: Miércoles 23 de Junio

La nueva era de websites en el internet cada vez más demandan la inclusión de una mejor experiencia de usuario (UX) en donde la interactividad, contenido multimedia y uso del sitio sea más sencillo y amigable para los usuarios.

Se ha dicho de que las versiones anteriores de Silverlight estaban muy orientadas a relizar animaciones y a presentar imagenes  y videos con mejor definición. Sin embargo desde la versión 3.0 y ahora en la versión 4.0 la capacidad de poder utilizar esta herramienta para hacer aplicaciones de linea de negocio es cada vez más sencillo.

Acompañanos a descubrir todas las novedades de Silverlight y WPF en VS2010

- Demistificando Silverlight y WPF 4.0

- Novedades

- Construcción de aplicaciones de linea de negocio.

- Construiremos una aplicación 0 a 100.

Sharepoint 2010 Development

Expositor: Manolo Herrera, Microsoft MVP Sharepoint, http://jmhogua.blogspot.com/

Fecha: Jueves 24 de Junio

El desarrollo en SharePoint nunca antes ha sido tan fácil y práctico

- Desarrollando en Web Part Visual para SharePoint en 15 minutos

- Depurando e instalando tu código en SharePoint desde Visual Studio con presionar una sola tecla.

- Descubriendo el nuevo Developer Dashboard de SharePoint

- Conociendo el Client Object Model de SharePoint desde un aplicación Windows.

- Creando una Sandbox Solution para que nos sirve y ayuda.

Web development con ASP.NET 4.0

Expositor: Cristian Prieto, Microsoft MVP ASP.NET, http://www.cprieto.com

Fecha: Viernes 25 de Junio

ASP.NET ha evolucionado muchísimo en los últimos años con la adición de ASP.NET MVC y Dynamic Data, además de las mejoras continuas a la plataforma de WebForms y ASP.NET AJAX. Hablaremos de como aumentar la productividad y al mismo tiempo construir aplicaciones web que manejen de una manera transparente CSS, controles finos sobre el renderizado y markup al mismo tiempo que podemos mejorar SEO y muchas otras características nuevas en ASP.NET 4.0

 

El cupo es limitado, así que sugiero que corran al link de registro y aparten su lugar http://bit.ly/launchgt

¡Espero verlos en el lanzamiento!

NOTA: Recuerden imprimir y llevar al evento el ticket de inscripción que se genera en el momento del registro

Saludos,

.NET y Configuraciones – Parte 6

Bueno, miren que lejos hemos llegado con el asunto de las configuraciones :) pero no se preocupen, aún falta mucho más que aprender sobre nuestros amigos los archivos app/web.config y sobre nuestras configuraciones personalizadas, imagínense un mundo con menos y con configuraciones más claras y con mayor significado para el desarrollador. Hasta el momento hemos explorado secciones, grupos de secciones, elementos, colecciones todas personalizadas, hoy aprenderemos un poco acerca de validadores.

Element Validators

Imagínense que en su sistema de configuración necesitan validar que el número ingresado por el usuario en la configuración se encuentre dentro de un rango, o que el texto ingresado cumpla con una expresión regular o cumpla una longitud mínima o máxima (si, ya se, ambos se pueden lograr con un regex, pero para efectos de ejemplo digamos que son dos diferentes). Muchos quizás nos veremos tentados a obtener el valor de la configuración y posteriormente validarlo, bien, en el caso de elementos de configuración es buena idea abstenerse de hacerlo. La buena noticia es que tenemos a nuestra disposición toda una infraestructura de validación de valores de configuración y esta se lleva a cabo en el momento en que el ConfigurationManager lee los valores.

Los Validators son atributos especiales que acompañan a nuestros elementos de configuración, podemos definir nuestros propios validadores (ese será el tema de un post futuro) pero por defecto la framework nos empaca un par de validadores simples y sencillos:

IntegerValidator Valida un entero dentro de un rango
LongValidator Valida un número dentro de un rango
PositiveTimeSpanValidator Valida un timespan dentro de un rango positivo
RegexStringValidator Valida que una cadena cumple con una expresión regular
StringValidator Valida que una cadena debe cumplir una longitud máxima/mínima
TimeSpanValidator Valida un timespan dentro de un rango

Usar los validadores no puede ser más sencillo, simplemente adornamos nuestras propiedades o elementos con el atributo del validador que nos interesa y la framework de configuración se encarga del resto

using System;
using System.Configuration;

namespace Samples {
    public class SampleConfigurationSection : ConfigurationSection {
        [ConfigurationProperty("port", DefaultValue = 80)]
        [IntegerValidator(MaxValue = 100, MinValue = 20)]
        public int Port {
            get { return (int) this["port"]; }
        }

        [ConfigurationProperty("host", IsRequired = true)]
        public string Host {
            get { return (string) this["host"]; }
        }

        [ConfigurationProperty("timeout")]
        [TimeSpanValidator(MinValueString = "00:00:00",
            MaxValueString = "00:01:00")]
        public TimeSpan Timeout {
            get { return (TimeSpan) this["timeout"]; }
        }
    }
}

Para probar la configuración podemos usar este simple app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="sample" type="Samples.SampleConfigurationSection, ValidatorSample"/>
  </configSections>
  <sample host="localhost" port="80" timeout="00:00:30" />
</configuration>

Y este pequeño programa de consola puede servirnos como simple prueba

using System;
using System.Configuration;

namespace Samples {
    internal class Program {
        private static void Main(string[] args) {
            var cfg = ConfigurationManager.GetSection("sample")
                as SampleConfigurationSection;
            if (cfg == null)
                return;

            Console.WriteLine("Host: {0}, Port: {1}, Timeout: {2}",
                cfg.Host, cfg.Port, cfg.Timeout);

            Console.ReadLine();
        }
    }
}

Si algún elemento no cumple con lo esperado por el validador el ConfigurationManager tirará una excepción de tipo ConfigurationErrorsException que a su vez en la propiedad Errors contendrá los ConfigurationException en forma de arreglo.