Simple Injector: Framework para IoC

Hace ya un tiempo habíamos visto en otro post de este blog un framework para realizar Inversion of Control o Dependency inversion principle (soliD), En aquella oportunidad vimos Autofac. Si bien es un framework muy bueno, lamentablemente no funciona al 100% en Mono.
Simple injector nos trae esa solución sin perder lo bueno que ya teníamos con el framework anterior. Además de Mono, soporta las plataformas: MVC 4.0 y superior, Silverlight 4.0 y superior, Windows phone 8 y Windows phone application.
Podemos descargarlo por NuGet y es muy simple de usar. Provee una fácil implementación con características cuidadosamente escogidas dentro de la librería. Sólo se requiere que la configuración de la librería se ejecute al inicio de la aplicación. Inclusive, a partir de la versión 2 se incluye la habilidad de advertir pérdidas de configuración mientras se ejecuta la aplicación en modo debug.


La idea general detrás de Simple Injector (o de la Inversión de Control en general) es que el diseño de la aplicación tengan un nivel bajo de acoplamiento entre sus componentes utilizando, como ya dijimos, el patrón de inversión de dependencias. Tomemos como ejemplo la siguiente clase, UserController, en el contexto de una aplicación ASP.Net MVC.

public class UserController : Controller {
    private readonly IUserRepository repository;
    private readonly ILogger logger;

    // Use constructor injection for the dependencies
    public UserController(IUserRepository repository, ILogger logger) {
        this.repository = repository;
        this.logger = logger;
    }

    // implement UserController methods here:
    public ActionResult Index() {
        this.logger.Log("Index called");
        return View(this.repository.GetAll());
    } 
}

La clase UserController depende de las interfaces IUserRepository y ILogger. Al no depender de una clase concreta, podemos realizar pruebas de la clase UserController de manera aislada. Y eso es sólo la punta del iceberg de las bondades de la inversión de control.
Usando Simple Injector, la configuración de la aplicación podría verse mas o menos así:

protected void Application_Start(object sender, EventArgs e) {
    // 1. Create a new Simple Injector container
    var container = new Container();

    // 2. Configure the container (register)
    container.Register<IUserRepository, SqlUserRepository>();

    container.RegisterSingle<ILogger>(() => new CompositeLogger(
        container.GetInstance<DatabaseLogger>(),
        container.GetInstance<MailLogger>()
    ));

    // 3. Optionally verify the container's configuration.
    container.Verify();

    // 4. Register the container as MVC3 IDependencyResolver.
    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}

Esta configuración muestra la registración de las implementaciones para las interfaces IUserRepository y ILogger. Este código también muestra un par de cosas interesantes. Primero que nada, se pueden asociar instancias concretas (como SqlUserRepository) a interfaces o tipos base. En el ejemplo anterior, cada vez que se solicita al contenedor de Simple Injector un IUserRepository, éste va a crear una nueva instancia de la clase SqlUserRepository.
La registración de ILogger es un poco más compleja. Se registra un delegado que conoce cómo crear una nueva implementación de ILogger, en este caso CompositeLogger (que resulta ser una implementación de ILogger). El mismo delegado es llamado dentro del contenedor de Simple Injector y crea una instancia concreta de la clase DatabaseLogger y MailLogger para inyectarlo dentro de CompositeLogger. Mientras el tipo de registración que hemos visto para IUserRepository es la más común, el uso de delegados permite muchos escenarios interesantes.
Nota: no se ha registrado la clase UserController. Esto se debe a que es una clase concreta. Simple Injector puede implícitamente crearla (siempre y cuando pueda resolver sus dependencias).
Esto es todo lo que se necesita para usar Simple Injector. Diseñar las clases basados en el principio de inversión de dependencias y configurar la librería al inicio de la aplicación. Algunos frameworks (tales como ASP.NET MVC) hacen el resto, mientras que otros (como ASP.NET Web forms) necesitan una vuelta más de trabajo para dejarlo hecho. Ver la guía de integración para consultar otros ejemplos de otros frameworks.

1 comentarios:

John Wayne dijo...

Muy bueno!

Publicar un comentario

Muchas gracias por leer el post y comentarlo.

 
Copyright 2009 Programación SOLIDa
BloggerTheme by BloggerThemes | Design by 9thsphere