Primeros pasos con StructureMap y la Inyección de Dependencias

26 nov. 2008
Uno de los objetivos que debe tener un buen programador es que su código esté poco acoplado, es decir, que dos componentes con funcionalidades distintas dependan el uno del otro lo mínimo posible. De esta forma conseguirá que sus dos componentes por separado sean reutilizables y más fáciles de mantener.

Para eliminar al máximo la dependencia entre componentes, existe un patrón de diseño conocido como “Inyección de dependencias” (“Dependency Injection” o DI).  Este patrón consiste básicamente en que en vez de ser una clase la que crea objetos, estos se inyectan o resuelven en el último momento.

Existen diferentes proyectos en .NET que intentan ayudarnos  a aplicar este patrón:
He decidido comenzar a utilizar StructureMap porque que es uno de los más extendidos y además me gusta su sintaxis y facilidad de uso.

Para comenzar a utilizar la inyección de dependencias debes acostumbrarte a utilizar interfaces en vez de objetos concretos ya que esto es lo que te permitirá diferentes implementaciones de esa interfaz.

Por ejemplo, si queremos un componentes que realice el registro de errores o eventos, crearemos una interfaz “ILogger”. Y además, dos implementaciones de esta interfaz, una para guardar los mensajes en una base de datos y otra en un archivo de texto.

public interface ILogger

{

    void Log(string message);

}

 

public class DatabaseLogger : ILogger

{

    public void Log(string message)

    {

        // Lógica para guardar el mensaje en un archivo d texto..

    }

}

 

public class TextLoggerILogger

{

    public void Log(string message)

    {

        // Lógica par aguardar el mensaje en un archivo de texto...

    }

}


Muy bien, ya tenemos dado el primer paso. Ahora añadiremos la referencia en nuestro proyecto a StructureMap.dll para poder utilizar esta librería.

Cuando queramos utilizar el objeto ILogger dentro de otra clase, llamaremos método GetInstance() del objeto ObjectFactory que ofrece StructureMap.

Por ejemplo

public class ClaseDePrueba

{

    public void HacerAlgo()

    {

        // ...

        ILogger logger = ObjectFactory.GetInstance<ILogger>();

        logger.Log("Mensaje que queremos registrar");

        // ...

    }

}


Pero te preguntarás, ¿cómo sabe StructureMap cuál de las dos implementaciones de ILogger debe devolver, la de la base de datos o la del  archivo de texto? Obviamente eso hay que indicárselo de alguna forma.

Podemos configurar StructureMap o bien utilizando el archivo de configuración App.config o Web.config si es una aplicación web. O mediante código, normalmente al iniciarse el programa o en el archivo Global.asax si trabajas con ASP.NET.

En este ejemplo, le indicaremos por código a StructureMap que queremos utilizar el archivo de texto para guardar los logs.

public void ConfigureStructureMap()

{

    ObjectFactory.Configure(

        s => s.BuildInstancesOf<ILogger>()

            .TheDefaultIsConcreteType<TextLogger>()

    );

}


¡Eso es todo! Ya estamos utilizando StructureMap y a partir de ahora, con cambiar una simple línea de código (o una línea del archivo de configuración si hubiéramos utilizado esa opción) podemos comenzar a utilizar la base de datos para guardar los mensajes en toda la aplicación.

La Inyección de dependencias es un patrón de diseño que todo programador debería conocer y utilizar. Además, esta técnica, unida al “Mocking”, te será realmente útil si utilizas (¡deberías hacerlo!) pruebas unitarias. Pero de esto ya hablaré en el futuro.

¡Espero vuestros comentarios!


comments powered by Disqus
subir