Evita las dependencias con tu contendor de IoC

Usar un contenedor de IoC es una práctica más que recomendable, pero al hacerlo es muy fácil caer en el anti-patrón de dependencia con el contenedor. Ese patrón se manifesta de varias formas sútiles, y aunque hay algunos casos en que pueda ser aceptable, en la gran mayoría indica una mala práctica que debemos revisar.

¿Que tiene de malo este código?

// IS1 y IS2 son dos interfaces cualesquiera
// S1 y S2 son dos clases que implementan dichas interfaces
class A
{
IS1 s1;
IS2 s2;
public A(IUnityContainer container)
{
this.s1 = container.Resolve<IS1>();
this.s2 = container.Resolve<IS2>();
}
}

class Program
{
static void Main(string[] args)
{
IUnityContainer ctr = new UnityContainer();
ctr.RegisterType<IS1, S1>();
ctr.RegisterType<IS2, S2>();
A a = ctr.Resolve<A>();
}
}

El código funciona correctamente, pero ¡ojo! Tenemos una dependencia directa de la clase A hacia IUnityContainer. Realmente la clase A depende de IUnityContainer o bien depende de IS1 y IS2? La realidad es que las dependencias de la clase A son IS1 e IS2.

1. La visión filosófica del asunto

Si yo leo el constructor de la clase A y veo que pone:

public A(IUnityContainer container)
{
// Código...
}

Debo leer todo el código del constructor para ver las dependencias reales de la clase A. Por otro lado si el constructor fuese:

public A(IS1 s1, IS2 s2)
{
// Código
}

Ahora queda mucho más claro que las dependencias reales de la clase A son IS1 y IS2.

En resumen: evitad en lo máximo de lo posible pasar el propio contenedor como parámetro de los constructores. En su lugar pasad las dependencias reales y dejad que el contenedor las inyecte.

Y obviamente evitad (casi) siempre un código como:

class A
{
IUnityContainer container;
public A(IUnityContainer container)
{
this.container = container;
}
// Código
}

¡Ahí estamos todavía más vendidos! Para averiguar las dependencias reales de la clase A, ahora debemos mirar todo el código de la clase A, puesto que en cualquier sitio alguien puede hacer un resolve (antes de que alguien salte por las paredes que eche un vistazo al punto 4 del post, por favor :p).

La visión “filosófica” me indica que si la clase A debería depender solo de IS1 e IS2 no es posible que me aparezca una dependencia sobre IUnityContainer. Necesita la clase A a IUnityContainer para hacer su trabajo? No, verdad? Pues eso.

Incluso aunque tengas claro, clarísimo que nunca vas a abandonar Unity (él no lo haría! :p) este código no huele nada bien.

2. La visión práctica

Algún dia quizá te canses e Unity y te decidas a usar por ejemplo, Windsor Container… Este cambio debería ser un cambio sencillo: un cambio en el bootstrapper de tu aplicación, y donde instanciabas Unity ahora instancias Windsor, lo configuras y listo!

Listo? Listo sólo si tus clases no dependen de IUnityContainer, porque en caso contrario… bueno, puedes tener un buen problemilla 😉

3. Algunos detalles…

Antes he comentado que este anti-patrón puede aparecer de formas realmente sutiles:

class A
{
public A()
{
//...
}
[Dependency()]
public IS1 S1 { get; set; }
// Más código
}

¿Es correcto este código? Mejor que el código anterior donde recibíamos IUnityContainer como parámetro si que es, porque no tenemos ninguna dependencia directa contra Unity… Pero realmente si que estamos dependiendo de Unity: Sólo Unity entenderá el atributo [Dependency()] para inyectarnos la propiedad S1. Así que a la práctica estamos como en el caso anterior.

Ahora bien, la diferencia fundamental es que, en mi opinión, que la clase A reciba IUnityContainer como parámetro rebela un mal diseño, mientras que en este caso la dependencia nos aparece porque no existe ningún mecanismo estándar para especificar que queremos que una propiedad sea inyectada (por lo que cada contenedor usa su propio mecanismo).

Si tienes claro, clarísimo que nunca abandonarás Unity, entonces no hay problema alguno en este código. Por otro lado si no quieres atarte al contenedor entonces este código no te sirve (echa un vistazo a mi post Unity? Sí gracias, pero no me abraces demasiado para ver más detalles al respecto).

4. Ya, pero yo uso el patrón Service Locator

Todo lo que hemos hablado hasta ahora afecta sobre todo en aquellos casos en que usábamos inyección de dependencias, pero existe otro patrón íntimamente relacionado: el service locator. En este patrón tenemos un objeto (el propio service locator) que se encarga de devolvernos referencias a servicios.

Es común que el propio contenedor de IoC se use como service locator, porque ofrece soporte directo para ello. Sin embargo no es una buena opción… porque conduce inevitablemente a situaciones como las que hemos visto, en concreto a situaciones como esta:

class A
{
private IUnityContainer serviceLocator;
public A(IUnityContainer serviceLocator)
{
this.serviceLocator = serviceLocator;
}
void foo()
{
// obtengo los servicios...
var logSvc = serviceLocator.Resolve<ILogService>();
var locSvc = serviceLocator.Resolve<ILocalizationService>();
// hago cosas con mis servicios
}
}

Este código es prácticamente igual al que os decía que debéis evitar a toda costa. Podríamos pasar ILogService e ILocalizationService en el constructor, pero ahora imaginad que tenemos muchos servicios y nuestras clases los usan todos (en un proyecto en el que estoy trabajando manejamos decenas de servicios, y además es común que las clases usen muchos de los servicios sólo en un método).

El error aquí, está en usar el propio contenedor como Service Locator: lo hacemos porque es rápido y cómodo ya que el contenedor nos ofrece soporte para ello, pero a cambio nos estamos atando al contenedor… Nosotros no queremos una dependencia contra IUnityContainer, sinó una dependencia contra el service locator. Y qué es el service locator? Pues algo distinto al propio contenedor. Por ejemplo, eso:

interface IServiceLocator
{
T GetService<T>() where T : class;
}
class ServiceLocator : IServiceLocator
{
private IUnityContainer container;
public ServiceLocator(IUnityContainer container)
{
this.container = container;
}

public T GetService<T>() where T : class
{
return this.container.Resolve<T>();
}
}

La clase ServiceLocator si que depende de Unity (ahí si que es inevitable la dependencia). Ahora la clase A la podemos reescribir como:

class A
{
private IServiceLocator serviceLocator;
public A(IServiceLocator serviceLocator)
{
this.serviceLocator = serviceLocator;
}
void foo()
{
// obtengo los servicios...
var logSvc = serviceLocator.GetService<ILogService>();
var locSvc = serviceLocator.GetService<ILocalizationService>();
// hago cosas con mis servicios
}
}

Y la clase A ya no depende de IUnityContainer: lo hace de IServiceLocator, lo que es aceptable y totalmente lógico.

Además, tener nuestra propia implementación del service locator nos permite adaptarlo a nuestras necesidades (p. ej. ¿qué hacer si nos piden un servicio que no está registrado?).

Así pues, usar el patrón service locator no es excusa para tener nuestro código lleno de dependencias contra el contenedor de IoC.

¿Opiniones? 😉

Un saludo a todos!

[ALM 09] Material de las sesiones: Surface y TDD

Hola a todos! Finalmente tuve el placer de dar no una, sino dos sesiones en las ALM Sessions 09. No era la idea inicial, pero mi compañero Juan Carlos finalmente no pudo dar la de Surface, así que la di yo (y es que por suerte o por desgracia me encanta hablar).

La primera sesión fue precisamente la de Surface, en el track de Diseño y UX. La intención inicial era haber traído la surface que tenemos en raona, pero por temas logísticos fue imposible… Así que tuve que dar una presentación sobre Surface sin Surface que es como una noche de fiesta sin lig… esto, que le falta algo, vamos. Intenté explicar un poco que es la Surface, y el cambio de paradigma que supone desarrollar para ella. Mostré el emulador que viene con el SDK de Surface (que os animo a todos a probar) y vimos algunos de los controles de dicho SDK. Finalmente exploramos el futuro que nos espera con WPF 4 unificando la programación multi-touch en Surface y en Windows 7.

La segunda sesión, en el track de arquitectura, versó sobre TDD. Intenté explicar que es TDD, pero sobre todo por que usar TDD sin entrar en detalles sobre el como hacer pruebas unitarias (lo que daria para varias sesiones). Luego mencioné los pequeños cambios que trae VS2010 para hacernos llevadera la tarea de realizar TDD (recordad las sabias palabràs del Capità Enciam: los pequeños cambios son poderosos) y empecé a desarrollar una clase usando TDD, intentando hacer énfasis en los pensamientos que uno tiene gracias a usar TDD. Me quedé un poco corto de tiempo y tambien me comentaron que la combinación de colores que tengo en mi VS2010 será muy cómoda para programar pero muy mala para proyectar… Disculpas por si no pudisteis ver bien el código por culpa de los colores 🙁

 

En fin, que más puedo deciros: yo me lo pasé en grande durante todo el evento: dando sesiones, escuchándolas, hablando y conociendo a gente… ah si! y también comiendo y bebiendo jejejee… 🙂

Os dejo las presentaciones de ambas sesiones.

Un saludo y nos vemos en la próxima movida!!! 😉

TxF – NTFS Transaccional

Una capacidad de la que no se habla mucho es de TxF, que apareció junto con Vista: es la capacidad de tener transacciones sobre ficheros NTFS. Esas transacciones pueden afectar a uno o a varios ficheros… y no solo eso: gracias al poder de DTS podemos coordinar una transaccion TxF con otros tipos de transacciones como SQL Server o MSMQ!

Como pasa con muchas de las características avanzadas de windows, sólo se puede usar en .NET a través de p/invoke (si obviamos C++/CLI claro)… vamos a ver un ejemplo!

Primero creamos una clase que contenga todas las definiciones de los métodos Win32 que vamos a usar:

public static class NativeMethods
{
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateFileTransacted(string lpFileName,
uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile, IntPtr hTransaction, IntPtr pusMiniVersion,
IntPtr pExtendedParameter);

[DllImport("ktmw32.dll", SetLastError = true)]
public static extern IntPtr CreateTransaction(IntPtr lpTransactionAttributes, IntPtr uow,
uint createOptions, uint isolationLevel, uint isolationFlags, uint timeout, string description);

[DllImport("ktmw32.dll", SetLastError = true)]
public static extern bool CommitTransaction(IntPtr transaction);

[DllImport("ktmw32.dll", SetLastError = true)]
public static extern bool RollbackTransaction(IntPtr transaction);

[DllImport("Kernel32.dll")]
public static extern bool CloseHandle(IntPtr handle);
}

Vamos a usar los siguientes métodos del api de Win32:

  • CreateFileTransacted: Crea o abre un fichero para ser usado de forma transaccional. Una vez obtenido el handle, el resto de funciones win32 que trabajan con handles funcionan transaccionalmente con el nuevo handle.
  • CreateTransaction: Crea la transaccion
  • CommitTransaction: Hace el commit de la transaccion 
  • RollbackTransaction: Hace el rollback de la transacción
  • CloseHandle: Cierra un handle cualquiera (sea de fichero o no y sea transaccional o no).

Vamos a hacer un programilla que abra dos ficheros en modo transaccional, escriba algo en ellos y luego haga commit y/o rollback de la transacción para ver sus efectos…

Primero creamos la transacción y abrimos dos ficheros (suponemos que los nombres nos los pasarán por línea de comandos):

// 1. Crear la transacción
IntPtr transaction = NativeMethods.CreateTransaction(IntPtr.Zero, IntPtr.Zero, 0, 0, 0, 0, null);
// 2. Abrir dos ficheros de forma transaccional
SafeFileHandle sfh1 = NativeMethods.CreateFileTransacted(args[0], NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE,
0, IntPtr.Zero, (uint)FileMode.CreateNew, 0, IntPtr.Zero, transaction, IntPtr.Zero, IntPtr.Zero);
SafeFileHandle sfh2 = NativeMethods.CreateFileTransacted(args[1], NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE,
0, IntPtr.Zero, (uint)FileMode.CreateNew, 0, IntPtr.Zero, transaction, IntPtr.Zero, IntPtr.Zero);

Una vez tenemos los handles cualquier función Win32 estándard para escribir o leer en ellos nos serviría… por suerte los file streams de .NET pueden ser creados a partir de un handle de Win32, así que podremos utilizar la clase FileStream.

Ahora ya sólo nos queda hacer un commit o un rollback… Para ello si se produce cualquier error durante la escritura haremos un rollback, y en caso contrario haremos un commit. Finalmente debemos cerrar la transacción y por ello usaremos CloseHandle.

El código es tal y como sigue:

try
{
// Escribimos algo en ambos ficheros
using (FileStream f1 = new FileStream(sfh1, FileAccess.ReadWrite))
using (FileStream f2 = new FileStream(sfh2, FileAccess.ReadWrite))
using (StreamWriter sw1 = new StreamWriter(f1))
using (StreamWriter sw2 = new StreamWriter(f2))
{
sw1.Write("Fichero 1");
if (args.Length > 2 && args[2] == "/e")
throw new IOException("Error cualquiera");
sw2.Write("Fichero 2");
}

// Lanzamos el commit. Si todo ha ido bien llegaremos aquí
NativeMethods.CommitTransaction(transaction);
}
catch (IOException ex)
{
// Algun error: lanzamos el rollback
Console.WriteLine("Error en el acceso a ficheros:" + ex.Message);
NativeMethods.RollbackTransaction(transaction);
}
finally
{
// Cerramos la transacción TxF
NativeMethods.CloseHandle(transaction);
}

Como se puede observar la escritura en los ficheros se hace a través de las clases estándard de .NET. Es solo la apertura del fichero que debe hacerse a través de la API de Win32, así como la creación de la transacción.

Si el tercer parámetro que se le pasa al programa es /e el programa simulará un error.

Si ejecutais el programa TxFDemo.exe f1.txt f2.txt vereis que os aparecen los dos ficheros.

Por otro lado si ejecutais TxFDemo f1.txt f2.txt /e vereis que NO os aparece ninguno de los dos ficheros, ya que se lanza la excepción y con ella se hace un rollback de la transacción NTFS.

Ahora imaginad las posibilidades que este sistema ofrece!

Eso sí recordad que es para Windows Vista o superior…

Link: Un artículo sobre TxF bastante interesante de Jason Olson.

Saludos!

ALM Sessions’09 – Test Driven Development

Hola a todos!! Este año tengo el placer de realizar una presentación en las ALM Sessions’09.

En concreto hablaré sobre Test Driven Development: que és, como su uso junto con otras buenas prácticas de desarrollo puede ayudarnos a ganar en calidad y como podemos implantarlo en un equipo de desarrollo.

También veremos que herramientas trae Visual Studio 2010 y como nos pueden ayudar a realizar de forma más sencilla TDD.

Os recomiendo que los que podais os paseis por Madrid este 24 de Noviembre, porque vale la pena. Si el año pasado las sesiones fueron buenas este año todavía más porque hay hasta 6 tracks simultáneos: Procesos, Calidad y testing, Herramientas, Arquitectura, Diseño/UX y Plataforma de aplicaciones. Si veis la agenda observaréis la gran cantidad de temas que se tratan. Es casi imposible no encontrar ninguno de vuestro interés!

Un saludo y nos vemos por allí!!!

image

Lifetime Managers en Unity o ¿como sé que eso que me das es un singleton?

Los que leais habitualmente mi blog (¡muchas gracias!) habreis visto que tengo varias entradas sobre unity el contenedor IoC de la gente de patterns & practices. En ellas he ido comentando varios aspectos más o menos avanzados del contenedor y de los patrones IoC associados.

En este post quiero hablaros un poco de los “lifetime managers”, objetos que le indican a Unity si cuando debe resolver un objeto debe crear uno nuevo o bien devolver uno existente.

Resumiendo mucho podemos afirmar que:

  1. Con RegisterType<IA, A>() lo que hacemos es registrar un mapeo de la interfaz IA a la clase A: cada vez que pidamos un objeto IA, usando Resolve<IA>(), el contenedor nos devolverá un nuevo objeto A.
  2. Con RegisterInstance<IA>(IA instance) lo que hacemos es registrar un singleton de la interfaz IA. Cada vez que pidamos un objeto IA, el contenedor nos devolverá el mismo objeto: el que hemos pasado como parámetro a RegisterInstance.

La realidad es, como casi siempre, un poco más compleja. Unity no distingue solamente los casos “crear un objeto cada vez” o “devolver siempre el mismo objeto”, sino que la decisión de si se debe crear un objeto nuevo o no se deriva en otra clase: el lifetime manager. De serie con Unity vienen 3 lifetime managers distintos:

  • TransientLifetimeManager: Cada vez que tengamos que devolver un objeto crearemos uno nuevo.
  • ContainerControlledLifetimeManager: Devolveremos siempre el mismo objeto (singleton).
  • PerThreadLifetimeManager: Devolveremos siempre el mismo objeto, pero crearemos un objeto para cada thread (singleton a nivel de thread).
  • ExternallyControlledLifetimeManager: Cada vez que tengamos que devolver un objeto devolveremos el mismo, si este sigue vivo (es decir el garbage collector no lo ha “recogido”). Obviamente Unity no mantiene una referencia al objeto sino una WeakReference, ya que en caso contrario el objeto estaría vivo “para siempre” dentro de Unity.

Tomemos la siguiente interfaz IA, y la clase A que la implementa:

public interface IA
{
Guid Id {get;}
}
public class A : IA
{
public Guid Id {get; private set;}
public A()
{
this.Id = Guid.NewGuid();
}
}

Cada objeto A creado tendrá su propio Id único.

Ahora miremos el siguiente código:

IUnityContainer container = new UnityContainer();

container.RegisterType<IA, A>(new ContainerControlledLifetimeManager());
IA a1 = container.Resolve<IA>();
IA a2 = container.Resolve<IA>();
Console.WriteLine("a1: " + a1.Id.ToString());
Console.WriteLine("a2: " + a2.Id.ToString());

Si ejecutáis el siguiente código observareis que el ID es el mismo: Unity nos ha devuelto el mismo objeto para las dos llamadas a container.Resolve<IA>(). Esto ha sido porque hemos especificado un ContainerControlledLifetimeManager como parámetro a la llamada RegisterType.

Si ahora modificamos el ContainerControlledLifetimeManager por un ExternallyControlledLifetimeManager el resultado es el mismo: ambos Resolve reciben el mismo objeto.

Ahora bien, si forzamos una recolección del Garbage Collector:

IUnityContainer container = new UnityContainer();
container.RegisterType<IA, A>(new ExternallyControlledLifetimeManager());
IA a1 = container.Resolve<IA>();
Console.WriteLine("a1: " + a1.Id.ToString());
a1 = null; // Importante! Si no es null, el GC no puede recojer el objeto!
GC.Collect();
IA a2 = container.Resolve<IA>();
Console.WriteLine("a2: " + a2.Id.ToString());

Ahora podemos observar como la segunda llamada a Resolve ha obtenido un objeto distinto al de la primera llamada (ya que el Garbage Collector ha eliminado el primer objeto).

Crear nuestros propios lifetime managers

Ahora que hemos visto que la realidad es un poco más divertida, la siguiente pregunta es: podemos crear nuestros propios lifetime managers? Y la respuesta es sí!

Para ello simplemente debemos crearnos una clase que herede LifetimeManager y que implemente los métodos:

  • SetValue: Que invoca Unity cuando ha creado el objeto. En este método podemos guardarnos el objeto creado.
  • GetValue: Donde devolvemos el objeto o bien null, para que Unity cree uno de nuevo (y luego nos invoque SetValue).
  • RemoveValue: Cuando se elimina un objeto

Una nota importante sobre RemoveValue: Unity nunca llama a este método, está ahí para que nosotros podamos eliminar objetos de Unity, siempre y cuando tengamos acceso al Lifetime manager.

Veamos un posible ejemplo de un Lifetime manager:

public class CustomLifetimeManager : LifetimeManager
{
private object[] values;
int idx = 0;

public CustomLifetimeManager(int instances)
{
values = new object[instances];
idx = -1;
}

public override void SetValue(object newValue)
{
values[idx] = newValue;
}

public override object GetValue()
{
idx = (idx + 1) % values.Length;
object value = values[idx];
return value;
}

public override void RemoveValue()
{
object value = values[idx];
values[idx] = null;
idx = (idx + 1) % values.Length;
if (value is IDisposable)
{
((IDisposable)value).Dispose();
}
}
}

El código se comenta casi solo, no? Este lifetime manager guarda x instancias del objeto, eso significa que Unity nos devolverá hasta x objetos distintos, y luego empezará a repetirlos.

P.ej. dado el siguiente código:

IUnityContainer container = new UnityContainer();
CustomLifetimeManager lft = new CustomLifetimeManager(3);

container.RegisterType<IA, A>(lft);

IA a1 = container.Resolve<IA>();
IA a2 = container.Resolve<IA>();
IA a3 = container.Resolve<IA>();
// Repes!
IA a4 = container.Resolve<IA>();
IA a5 = container.Resolve<IA>();
IA a6 = container.Resolve<IA>();

Hemos configurado nuestro CustomLifetimeManager para que nos de hasta tres objetos distintos. Los tres primeros Resolve recibirán cada uno un objeto nuevo distinto… pero luego el cuarto resolve recibirá de nuevo el primer objeto, el quinto recibirá el segundo y así sucesivamente: hemos creado un pool de objetos.

Como veis es realmente fácil, crearos vuestros propios lifetime managers, lo que os permite personalizar al máximo cuando Unity debe crear un objeto nuevo o devolver uno ya existente!

Un saludo!

IList<T>.Count vs IEnumerable<T>.Count() (LINQ)

Te has preguntado alguna vez la diferencia de rendimiento que pueda haber entre el método extensor Count() proporcionado por LINQ y la propiedad Count de la interfaz IList<T>.

Es decir dado el siguiente código:

List<int> lst = new List<int>();
// Añadimos ints a la lista...
// Qué es más rápido?
var count = lst.Count;
var count2 = ((IEnumerable<int>)lst).Count();

A veces hacemos suposiciones sobre como funciona LINQ to objects. Uno puede pensar que el método Count() de LINQ está definido como:

public static int Count<T>(this IEnumerable<T> @this)
{
int count = 0;
foreach (var x in @this) count++;
return count;
}

Hay gente que basándose en estas suposiciornes intenta evitar el uso de Count() cuando sabe que la colección real es una List<T> p.ej. Desgraciadamente esto les lleva a no poder hacer métodos genéricos con IEnumerable<T> (empiezan a trabajar con IList<T>). A veces comentan que usarían mucho más LINQ to Objects, pero que trabajan habitualmente con listas, y que no pueden permitirse el sobrecoste de recorrer toda la lista simplemente para contar los elementos, cuando la clase List<T> ya tiene una propiedad para ello…

… están totalmente equivocados.

LINQ to Objects está optimizado, no es un proveedor tan tonto como algunos piensan… Así realmente si el objeto sobre el que usamos Count() implementa ICollection o ICollection<T>, LINQ usará la propiedad Count directamente, sin recorrer los elementos.

Para que veais que es cierto he realizado un pequeño test:

class Program
{
static void Main(string[] args)
{
List<int> list = new List<int>();
for (int i = 0; i < 10000000; i++)
{
list.Add(i);
}

Stopwatch sw = new Stopwatch();
sw.Start();
CountList(list);
sw.Stop();
Console.WriteLine("List.Count:" + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
CountLinq(list);
sw.Stop();
Console.WriteLine("LINQ.Count():" + sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
CountLoop(list);
sw.Stop();
Console.WriteLine("foreach count" + sw.ElapsedMilliseconds);
sw.Reset();
Console.ReadLine();
}

static void CountList (IList<int> list)
{
for (int i=0; i< 100; i++)
{
var a = list.Count;
}
}

static void CountLinq(IEnumerable<int> list)
{
for (int i = 0; i < 100; i++)
{
var a = list.Count();
}
}

static void CountLoop(IEnumerable<int> list)
{
for (int i = 0; i < 100; i++)
{
var a = list.Count2();
}
}
}

El test cuenta 100 veces una lista con 10 millones de elementos, y cuenta lo que se tarda usando la propiedad Count de la lista, el método Count() de LINQ y el método Count2, que es un método extensor que recorre la lista (es exactamente el mismo método que he puesto antes).

Los resultados no dejan lugar a dudas:

  1. Usando la propiedad Count, se tarda menos de un ms en contar 100 veces la lista.
  2. Usando el método Count() de LINQ se tarda igualmente menos de un ms en contar la lista 100 veces.
  3. Usando el método extensor Count2 se tarda más de 9 segundos en contar la lista 100 veces…

Si en lugar de 100 veces la contamos diez millones de veces, los resultados son:

  1. 30 ms usando la propiedad Count
  2. 247 ms usando el método Count() de LINQ
  3. Ni idea usando el método extensor Count2… pero vamos si para 100 veces ha tardado 9 segundos… para diez millones… no quiero ni pensarlo!

Los tiempos han sido medidos con la aplicación en Release.

La conclusión es clara: no tengáis miedo a LINQ, que MS no ha hecho algo tan cutre como un triste foreach!! 😉

Saludos!

PD: En este post del blog del equipo de C# cuentan esta y otras optimizaciones más de LINQ to Objects… lectura imprescindible! 🙂

Code Contracts, Pruebas Unitarias y SandCastle (y los materiales del CodeCamp)

Buenas! Como prometí en el post anterior sobre el CodeCamp, en mi charla sobre Code Contracts, quedaron por ver algunos temillas que aprovecho para comentar ahora.

Pruebas Unitarias

Primero remarcar que no realiceis pruebas unitarias para validar que vuestros contratos están bien, es decir, si teneis un método:

public void Foo(int arg)
{
Contract.Requires(arg > 0);
}

No hagáis una prueba unitaria que compruebe que el contracto falla si se le pasa cero a arg.

¿Por qué no hacer esta prueba? Pues por dos razones.

La primera es “filosófica”: Un contrato fallado significa código erróneo, y no tiene sentido que una prueba unitaria que es código erróneo funcione correctamente.

La segunda es más práctica: Qué va a suceder cuando el contrato falle? Code Contracts dos modos de funcionamiento (se realiza un Asert, o bien se lanza una excepción), pero podemos añadir nuestro propio comportamiento. Además la prueba unitaria no debería asumir nada en cuanto al comportamiento de Code Contracts, ya que ese es variable por configuración (recordad que incluso podríamos tener todos los contratos deshabilitados en Release).

Si un contrato se rompe durante la ejecución de la prueba unitaria, la prueba debería fallar, con independencia del comportamiento en que tengamos configurado Code Contracts. Para ello puede usarse el evento ContractFailed, de la clase Contract, que se lanza cada vez que un contrato se rompe. El siguiente código lo podéis usar a tal efecto:

/* Convierte los fallos de contrato en fallos de Tests */
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext tc)
{
Contract.ContractFailed += (sender, e) =>
{
e.SetHandled();
e.SetUnwind();
Assert.Fail(e.FailureKind.ToString() + ":" + e.Message);
};
}

Nos suscribimos al evento ContractFailed y en él:

  1. Indicamos a Code Contracts que no realice el comportamiento por defecto. P.ej. si Code Contracts estaba configurada para lanzar una excepción evitamos que la lance.
  2. Fallamos la prueba unitaria (mostrando cual es el contrato fallado).

De esta manera podéis “olvidaros” de Code Contracts y realizar pruebas unitarias que verifiquen vuestro código en lugar de los contratos, con la total seguridad de que si en cualquier momento un contrato falla, la prueba unitaria os lo verificará!

Sandcastle

Sandcastle es la herramienta para generar archivos de ayuda a partir de los comentarios XML en código fuente. No es excesivamente agradable de utilizar, aunque por suerte existe SandCastle Help File Builder, una GUI sobre Sandcastle que convierte su uso en casi trivial (si lo usáis sabed que puede integrarse con Team Build).

Los contratos son un elemento fundamental de los métodos y de una clase, pero sandcastle no los soporta (la última versión de sandcastle es mayo del 2008). Code contracts viene con un parche para sandcastle que se instala encima de sandcastle y que añade soporte para contratos. Con este parche instalado, podemos utilizar nuevas etiquetas xml, en nuestra documentación:

/// <summary>
/// Construye la pila de un tamaño máximo indicado.
/// </summary>
/// <param name="size">Tamaño máximo</param>
/// <requires />
public Pila(int size)
{
Contract.Requires(size > 0, "Tamaño inicial mayor que cero");
// Código...
}

P.ej. en este caso la etiqueta <requires /> indica que queremos documentar las precondiciones de este método. Luego en código utilizamos una sobrecarga de Contract.Requires que permite especificar un mensaje. Este mensaje es el que usa cuando falla el contrato, y también es el que usará sandcastle. Si no ponemos la etiqueta <requires /> las precondiciones no se documentarán aunque existan llamadas a Contract.Requires. Si alguien se pregunta porqué, es lo mismo que ocurre con el resto de documentación. P.ej. si no ponemos una etiqueta <param> no se documenta un parámetro de método, aunque éste exista.

El resultado será algo parecido a lo siguiente:

image

Como se puede observar se incluye un apartado “Contracts” con las precondiciones. Igual que existe la etiqueta <requires /> existen otras como <ensures /> para las postcondiciones,… Están todas ellas documentadas en el manual de Code Contracts.

Y el material del CodeCamp…

Aunque se lo mandaré a la organización para que lo cuelguen en la web del codecamp os dejo aquí el enlace al material de mi charla del codecamp. Son varias demos, que se auto-explican bastante y el ppt usado. Para cualquier duda… ya sabéis donde encontrarme!

 

Saludos!

De resaca… del codecamp!

Pues sí… han pasado ya dos días, pero yo todavía estoy resacoso del Code Camp 2009 de Tarragona.

Fue una experiencia brutal, tanto en lo organizativo, como en lo técnico pero sobretodo en lo humano… compartir este fin de semana con gente apasionada de la tecnología .NET, sea en entornos MS o en Mono, es simplemente increíble.

El éxito de gente también debe mencionarse: unas 250 persones el sábado, y un poco menos el domingo, pero más de las que yo me esperaba. En mi caso yo daba una charla sobre “Code Contracts”, el domingo a las 09:00 (jejeeee… a los malos ponentes nos meten en la peor hora :P), en la que hubo bastante más gente de la que me pensaba. Además pienso que el tema interesó bastante, aunqué no me dio tiempo de contar todo lo hubiese deseado. Pude comentar que son los contratos de código y por qué deben  usarse. Luego vimos ejemplos de precondiciones, postcondiciones e invariantes y poca cosa más…

… me quedó en el tintero como hacer tests unitarios cuando tenemos contratos (aunque pronto colgaré un post al respecto), y la integración con Sandcastle. De todos modos, estará toda la información (con ejemplos) disponible en la web del codecamp. Y por supuesto si alguien tiene alguna duda o interés al respecto, que contacte conmigo!

Gracias a todos los que vinisteis al codeamp, y espero que nos veamos en el próximo, sea donde sea!!

Saludos!

¿MVP e IoC trabajando juntos? ¡Pues claro!

Un comentario de Galcet en mi post “Como independizar tu capa lógica de tu capa de presentación” decía que el entendía por separado los conceptos de IoC y los de MVC pero que no veía como podían trabajar juntos… El motivo de este post es para comentar precisamente esto: no sólo cómo MVC e IoC pueden trabajar juntos sinó las ventajas que la combinación de ambos patrones nos aporta.

Galcet no comentaba si se refería a aplicaciones desktop o web. En este post voy a tratar aplicaciones de escritorio (por lo que me centraré en el patrón MVP más que en el MVC dado que, en mi opinión, MVP aplica mejor que MVC en aplicaciones desktop). En aplicaciones web, si usamos ASP.NET MVC el tema se simplifica mucho, dado que ASP.NET MVC está “preparado” para que sea muy fácil crear nuestros controladores mediante cualquier contenedor IoC.

La filosofía CAB + SCSF

CAB (o Composite UI Application Block) es un framework para el desarrollo de aplicaciones de escritorio winforms con interfaz de usuario compleja. Se basa en el patrón MVP y se compone de varios assemblies y una guía de buenas prácticas. Aunque puede usarse sola, suele combinarse con SCSF (Smart Client Software Factory), un conjunto de guías, librerías y buenas prácticas para la creación de aplicaciones winforms complejas. La recomendación de SCSF para la interfaz de usuario es usar CAB, y de hecho extiende CAB. No voy a hablar aquí ni de CAB ni de SCSF (hay varios tutoriales en internet), sino de como CAB y SCSF afrontan el uso de IoC junto con MVP.

La filosofía de SCSF es que nosotros creamos las vistas y las vistas crean a su presenter asociado. El código equivalente usando Unity sería algo parecido a:

public class View : UserControl, IView
{
public View ()
{
InitializeComponents();
// Resto de código...
}
private IMyPresenter _presenter;
[Dependency()]
public IMyPresenter Presenter
{
get { return _presenter;}
set
{
_presenter = value;
_presenter.View = this;
}
}
}
public class MyPresenter : IPresenter
{
public IView View { get; set;}
}

El contenedor debe tener registrado el mapping entre las interfaces y las clases:

container.RegisterType<IPresenter, MyPresenter>();

container.RegisterType<IView, View>();
// Creamos la vista
var view = container.Resolve<IView>();

Al llamar al método Resolve, Unity consulta sus mappings y llega a la conclusión de que debe crear un objeto View. La clase View tiene una propiedad “Presenter” decorada con [Dependency()], por lo que Unity debe inyectar un valor a esta propiedad. La propiedad es de tipo IMyPresenter, Unity consulta sus mappings y vee que debe crear un objeto de la clase MyPresenter. Luego en el setter de la propiedad “Presenter” la vista se asigna a si misma como vista del presenter recién creado.

A lo mejor alguien se pregunta porque no usamos inyección de dependencias en el constructor del presenter, es decir que en lugar de que nuestro presenter declare una propiedad que reciba la vista y rellenar esta propiedad desde la propia vista, declaramos la vista en el constructor y que Unity se encargue de todo:

public class View : UserControl, IView
{
public View ()
{
InitializeComponents();
// Resto de código...
}
private IMyPresenter _presenter;
[Dependency()]
public IMyPresenter Presenter { get; set;}
}
public class MyPresenter : IPresenter
{
public MyPresenter (IView view)
{
// Nos guardamos la vista...
}
}

¿Qué problema hay en este código? A priori puede parecer que ninguno, pero si repasamos como actuaría Unity:

  1. Al llamar a Resolve<IView> Unity consulta sus mappings y ve que debe crear un objeto de la clase View
  2. Al inyectar la propiedad Presenter, Unity consulta sus mappings y ve que debe crear un objeto de la clase MyPresenter
  3. Al intentar crear un objeto MyPresenter, Unity observa que el constructor recibe un IView y que debe inyectarlo.
  4. Así pues, Unity consulta sus mappings y crea un nuevo objeto View que inyectará en el constructor del MyPresenter.

Suponiendo que todo esto no terminase en un Stack Overflow, en todo caso el objeto MyPresenter recibiría un objeto View distinto del que devolvería la llamada a Resolve.

El “problema” de Visual Studio

¿Porque ha optado CAB por esta filosofía? ¿Porque las vistas crean a los presenters y no al revés? ¿Porque la inyección de dependencias es por propiedades y no en el constructor? La respuesta a todos estos interrogantes se llama Visual Studio.

Me explico: si tenemos una vista (o sea un UserControl) llamada View, cuando la arrastramos dentro de un formulario, o de un panel Visual Studio genera un código parecido a:

View view1 = new View();
panel1.Controls.Add(view1);

¿Observáis el problema? Visual Studio ha creado una instancia de la vista, usando new, no usando el método Resolve del contenedor de IoC, por lo tanto nos podemos olvidar de la inyección de dependencias, por lo que efectivamente nuestro presenter no estará creado.

¿Como podemos solucionar este problema? Bueno… todos los controladores IoC permiten “inicializar” un objeto ya creado, entendiendo por “inicializar” inyectar todas las dependencias que este objeto necesita (en el caso de nuestras vistas, la propiedad “Presenter”). En el caso de Unity este método se llama BuildUp, y se le pasa la instancia del objeto a inicializar. Lo que debemos hacer es inicializar todos los controles que estén en el formulario, lo que podemos hacer en el método Main:

[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 frm = new Form1();
IUnityContainer container = new UnityContainer();
frm.BuildUpControls(container);
Application.Run(frm);
}

Donde el método “BuildUpControls” es un método de extensión definido de la siguiente manera:

public static class FormExtensions
{
public static void BuildUpControls (this Control self,
IUnityContainer container)
{
container.BuildUp(self);
foreach (Control control in self.Controls)
{
control.BuildUpControls(container);
}
}
}

El método BuildUpControls va recorriendo recursivamente la colección “Controls” para llamar al método “BuildUp” del contenedor con todos los controles creados. En este caso no miramos nada más, por lo que inicializamos todos los controles (incluso las labels, los textboxes…), lo que es excesivo. Un refinamiento es inicializar sólo aquellos controles que sean “vistas”. Por ejemplo, CAB para saber que un control es una “vista” y que debe ser inicializado obliga a decorarlo con el atributo [SmartPart].

Evidentemente si nosotros mismos añadimos en run-time una vista debemos inicializarla “manualmente”:

Subview view = new Subview();
view.BuildUpControls(container);
// O bien...
Subview view = container.Resolve<Subview>();

Eso mismo ocurre en CAB: si en CAB creamos una vista de forma programática también debemos “inicializarla”. CAB gestiona la inicialización de una forma totalmente distinta, pero la filosofía es la misma (que es lo que intento contar).

Pues bueno… hemos visto como podemos combinar el uso de un contenedor IoC (como siempre en mi caso Unity :p) junto con el patrón MVP. Fijaos que los presenters si que están creados por Unity, por lo que pueden recibir dependencias inyectadas en el constructor (p.ej. a un servicio de log).

Un saludo!

IoC o el poder de ceder el control (ii): Dependency Injection

Hace ya algún tiempecillo publiqué por aquí un post sobre IoC, titulado IoC o el poder de ceder el control. En el post mencionaba dos de los patrones clásicos asociados con IoC, el service locator y la inyección de dependencias (dependency injection), pero luego sólo me centraba en Service Locator. Un par de comentarios en dicho post decían si era posible algo similar pero explicando la inyección de dependencias, así que a ello vamos 😉

Dependencias de una clase

Para entender como funciona la inyección de dependencias tenemos que tener claro que entendemos por dependencias de una clase: Básicamente una clase tiene dependencias con todas las otras clase que utilice, ya sea reciba objetos de dicha clase como parámetros, los devuelva como valores de retorno o cree variables locales o de clase.

Las dependencias no son nada malo y de hecho no son evitables: es evidente que las clases cooperan unas con otras para realizar alguna acción conjunta, así que es lógico que nuestro código depende de otras clases. Lo que debe preocuparnos es el acoplamiento de nuestro código con estas dependencias, o dicho de otro modo: cuanto nos costaría cambiar nuestra clase para que en lugar de depender de una clase X, dependiese de otra clase Y que ofrece la misma funcionalidad. Si has de modificar muchas líneas de código es que tienes un alto acoplamiento (y eso sí que es malo). El objetivo de la inyección de dependencias es facilitarte conseguir un acoplamiento lo más bajo posible.

Alto acoplamiento: uso directo de clases

El nivel de acoplamiento mayor es cuando nuestros métodos trabajan con parámetros cuyo tipo es una clase:

public class X
{
public MyLogClass Logger { get; private set;}
public X (MyLogClass logger)
{
this.Logger = logger;
}
}

La clase X tiene un alto acoplamiento con la clase MyLogClass. Si quisiéramos cambiar MyLogClass por otra clase distinta, llamésmole MyLogClass2 que tenga la misma funcionalidad deberemos modificar la clase X para que la propiedad Logger sea de tipo MyLogClass, asi como modificar el constructor… Parece sencillo, pero tened en cuenta que nuestra clase X será llamada por varias clases distintas. Todas las clases que crean un objeto de X, crearán un objeto MyLogClass para pasarlo como parámetro al constructor: deberemos cambiar también todas estas clases.

Un cambio que debería ser fácil y que debería afectar sólo a una clase, se convierte, por culpa de alto acoplamiento, en un cambio complejo, que afecta a multitud de clases.

Acoplamiento medio: Interfaces

Las interfaces ayudan solucionar el problema. Podemos definir la clase X para que trabaje con interfaces:

public class X
{
public ILogger Logger { get; private set;}
public X (ILogger logger)
{
this.Logger = logger;
}
}

Ahora la clase X no tiene dependencia alguna con MyLogClass. Podemos utilizar MyLogClass, MyLogClass2 o cualquier clase que implemente ILogger.

Pero el problema no está resuelto al 100%. Para crear objetos de la clase X, debemos pasarle en el constructor un objeto de una clase que implemente ILogger:

MyLogClass logger = new MyLogClass();
X x = new X(logger);

Es decir la clase X no depende de MyLogClass, pero todas aquellas clases que crean objetos de la clase X sí, ya que deben crear un MyLogClass para pasarlo como parámetro al constructor. De nuevo modificar MyLogClass por MyLogClass2 implica localizar todos aquellos sitios donde se crean objetos de X y modificarlo.

Acoplamiento bajo: Interfaces + Factoría

Llegados a este punto alguien puede tener la idea “hey! porque no creamos una factoria de ILogger, que sea la responsable de crear los objetos?”. Es una gran idea ya que mueve todas las dependencias a la clase en UN sólo sitio, la factoría:

public static class ILoggerFactory
{
public static ILogger GetLogger()
{
return new MyLogClass();
}
}

// ... Luego en cualquier otro sitio ...
X x = new X (ILoggerFactory.GetLogger());

Ahora si en lugar de querer usar MyLogClass queremos usar MyLogClass2 sólo debemos modificar la factoría.

Hey! Y todo eso sin usar IoC… entonces para que el post? Bueno… imagina que por cualquier razón, debes modificar el constructor de X para que acepte algún otro parámetro:

public class X
{
public X (ILogger log, IFormatter frm);
}

Sigue imaginando que, por la razón que sea, no puedes seguir teniendo el constructor con un solo parámetro ILogger, ya que no puedes asignar ningún valor por defecto a IFormatter. Pues bien… en este caso de nuevo debes volver a localizar todas las llamadas al constructor de X y modificarlas para pasar el nuevo parámetro  (que por supuesto sacarás de otra factoría que crearás).

Por suerte no estamos en un callejón sin salida: la inyección de dependencias viene para solucionar este pequeño problema.

Acoplamiento muy bajo: Inyección de dependencias

La inyección de dependencias se basa en el mismo principio que la factoría: No creas tu los objetos directamente, sinó que delegas esta responsabilidad en alguien. La diferencia respecto a la factoría tradicional, es que este alguien es un contenedor de IoC, capaz de crear todos aquellos parámetros necesarios e inyectarlos en el constructor. Si añades un parámetro nuevo, apenas deberás hacer nada: el contenedor de IoC automáticamente sabrá inyectar este nuevo parámetro.

Vamos a ver un ejemplo usando Unity, el contenedor IoC de la gente de Patterns & Practices. Primero comento muy rápidamente los conceptos básicos de Unity.

La gracia está en mapear un tipo a una interfaz, con esto le decimos al contenedor que cuando pidamos objetos de una interfaz nos devuelva objetos de una clase determinada. Esto en Unity se consigue con el método RegisterType:

IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, MyLogClass>();

Cuando pidamos un ILogger, Unity nos devolverá un MyLogClass… Y como le pedimos a Unity un ILogger? Pues usando el método Resolve:

ILogger logger = container.Resolve<ILogger>();

Hasta aquí todo muy parecido a la factoría. Ahora viene lo bueno: Si tenemos mappings registrados en Unity para las interfaces, Unity puede inyectar estos mappings en cualquier constructor. Es decir:

container.RegisterType<ILogger, MyLogClass>();
container.RegisterType<IFormatter, MyFormatClass>();
X x = container.Resolve<X>();

Con las dos primeras líneas hemos configurado nuestro contenedor de IoC para que sepa que devolver cuando se le pida un ILogger y un IFormatter. Con la tercera línea estamos pidiendo un objeto de tipo X. Entonces Unity hace lo siguiente:

  1. Mira si tiene algún mapeo que mapee X a una clase en concreto (en principio Unity no sabe que X es una clase y no una interfaz).
  2. Al no tenerlo, deduce que es una clase y que debe crear un objeto de la clase X. Para ello inspecciona la clase X, y ve que el constructor requiere dos parámetros, un ILogger y un IFormatter.
    1. Unity resuelve el primer parámetro
    2. Unity resuelve el segundo parámetro
    3. Unity pasa los valores de los dos parámetros resueltos al constructor de la clase X y devuelve el objeto X creado. Es decir, Unity inyecta los parámetros necesarios en el constructor.

Es decir, lo que Unity hace por nosotros es equivalente a si hubieramos hecho:

ILogger p1 = container.Resolve<ILogger>();
IFormatter p2 = container.Resolve<IFormatter>();
X x = new X(p1, p2);

Llegados a este punto… si se modificase el constructor de la clase X para hacer aparecer un tercer parámetro… tan sólo debemos hacer una modificación en nuestro código: Donde configuramos el contenedor de Unity, poner una llamada más a RegisterType(), para que Unity sepa que devolver cuando se encuentre un parámetro de dicho tipo. Pero dado que en nuestro códgo siempre obtenemos instancias de X llamando a container.Resolve<X>(), no deberemos modificar ninguna línea más de nuestro código.

Llegados a este punto, comentaros dos cosillas:

  1. Lo que hemos visto se llama inyección de dependencias en el constructor, y es uno de los mecanismos más normales. Otra forma común de inyectar dependencias es usar propiedades: es decir, el contenedor IoC al crear el objeto, inyecta valores en todas las propiedades que nosotros le indiquemos.
  2. Que ocurre en aquellos objetos que por cualquier razón NO pueden ser creados por el contenedor (p.ej. objetos que un framework cree por nostros)? Podemos hacer que estos objetos reciban inyección de dependencias?

La respuesta al punto (2) la da el punto (1): Podemos utilizar inyección de dependencias en propiedades y luego, una vez tenemos el objeto ya creado, decirle al contenedor IoC que inyecte las dependencias pendientes. Esto en Unity se hace mediante el método BuildUp, que toma un objeto e inyecta las dependencias pendientes. Por ejemplo imaginad que deserializamos un objeto y queremos que el objeto deserializado reciba dependencias del contenedor de IoC. Es evidente que no podemos poner las dependencias en el constructor (porque no controlamos quien crea el objeto), pero podemos poner las dependencias en propiedades y una vez tenemos el objeto indicarle al contenedor de IoC que inyecte dichas propiedades. Esto en Unity se consigue mediante el método BuildUp.

public class X
{
// Código variado...

// El atributo Dependency indica a Unity que la propiedad debe
// ser inyectada
[Dependency()]
[XmlIgnore()]
public ILogger Logger { get; set;}
}

// En cualquier otro sitio...

X x = null;
XmlSerializer ser = new XmlSerializer(typeof(X));
x = (X)ser.Deserialize(myStream);
// Inyectamos las propiedades
container.BuildUp(x);

Cuando leemos el stream myStream, el propio XmlSerializer nos crea un objeto de la clase X. Luego al llamar al método BuildUp, es cuando el contenedor de IoC inyectará las propiedades.

Así es como funciona (más o menos :p) la inyección de dependencias.

Un saludo a todos!