[C#] Microsoft Unity II – Iniciando con Unity

Posted on Actualizado enn


Post de la serie:

Hola, en el anterior post (dale una mirada acá) se habló sobre las ventajas y características de utilizar Inyección de Dependencias, sin embargo no vimos nada de código, por lo que hoy si vamos a tirar algunas lineas para ir mirando su funcionamiento.

En el post anterior comentaba que uno de los principios básico de la DI es trabajar contra abstracciones y no contra implementaciones, y en resumen podemos decir que vamos a trabajar contra interfaces y no contra clases, no voy a entrar en detalle sobre el cómo funcionan las interfaces (lo podemos tratar en otro post), así que solo vamos a ver un pequeño ejemplo en donde tenemos una clase que se encarga de guardar en un log (en los ejemplos voy a estar utilizando ASP.NET MVC, pero aplican a cualquier tipo de proyecto):

public class LogFile
{
	public void Log(string msg)
	{ 
		//TODO: Log the msg
	}
}
public class HomeController : Controller
{
	private readonly LogFile log;

	public HomeController()
	{
		log = new LogFile();
	}

	public ActionResult Index()
	{
		log.Log("Action: Index");
		return View();
	}
}

Revisando el código anterior, es claro que nuestro HomeController que no es más que una clase depende totalmente de la clase LogFile, en este caso se dice que tenemos un fuerte acoplamiento, ya que la clase HomeController conoce totalmente a LogFile, bueno pero vamos ahora a reescribir un poco el código para trabajar contra interfaces y tener un poco menos de acoplamiento; lo primero es crear una interfaz ILog para que sea implementada por la clase LogFile:

public interface ILog
{
	void Log(string msg);
}
public class LogFile : ILog
{
	public void Log(string msg)
	{ 
		//TODO: Log the msg
	}
}

Bueno, hasta el momento solo ha sido un pequeño cambio, ahora es momento de cambiar HomeController para trabajar contra la interfaz y no con la clase específica:

public class HomeController : Controller
{
	private readonly ILog log;

	public HomeController(ILog log)
	{
		this.log = log;
	}

	public ActionResult Index()
	{
		log.Log("Action: Index");
		return View();
	}
}

Si ahora revisamos HomeController, por ningún lado aparece la clase LogFile, y HomeController solo conoce la interfaz ILog, es decir solo tiene conocimiento de lo que hace más no de cómo lo hace, y otro punto importante, en el constructor de la clase le inyectamos la dependencia. Si en este punto probamos la aplicación vamos a obtener un error, y por el momento les dejo dos posibles soluciones Creando una factoría de controladores personalizada e Inyectando dependencias con Microsoft Unity.

Bueno pero hasta el momento nada de Unity…y es acá donde iniciamos a hablar de él. Unity es una herramienta que se conoce como un DI Container o un contenerdo de inyección de dependencias (existen muchos otros bastante buenos), y la idea básicamente es tener un sitio componente especializado en donde registremos todas las dependencias y como se van a resolver, además se va a encargar de manejar el tiempo de vida de cada componente registrado (lo trataremos en otro post de la serie) entre otros.

Ahora manos a la obra, lo primero es añadir la referencia a Unity mediante Nuget, en este caso buscamos por Unity y escogemos Unity bootstrapper for ASP.NET MVC:

unity II - img I

El paquete anterior añade un par de clases en el folder App_Start:

  • UnityConfig: Acá se van a registrar las dependencias.
  • UnityMvcActivator: Es llamada cuando se inicia la aplicación (ya que es del tipo WebActivator) y se encarga de crear el contenedor de Unity.

Luego de tener ya listo nuestro contenedor, el siguiente paso es comenzar a registrar nuestras dependencias, pero antes de hacerlo revisemos tres métodos (que hacen parte del ciclo de ejecución) claves en Unity:

  • RegisterType: Es utilizado para relacionar o definir el mapping entre la interfaz y el tipo concreto que se va a utilizar, la sintaxis básica es container.RegisterType<Interfaz,TipoConcreto>(); en otro post de la serie revisaremos las otras formas de registrar y crear los mappings.
  • Resolve: Es utilizado para obtener el tipo concreto de una interfaz, la sintaxis es: container.Resolve<Interfaz>();
  • Dispose: Se encarga de liberar recursos.

Ahora para registrar las dependencias, vamos a la clase UnityConfig, más exactamente en el método RegisterTypes y allí realizamos el registro de la dependencia, para el ejemplo solo será para la interfaz ILog, por el momento la clase debe verse algo así:

public class UnityConfig
{
	#region Unity Container
	private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
	{
		var container = new UnityContainer();
		RegisterTypes(container);
		return container;
	});

	/// <summary>
	/// Gets the configured Unity container.
	/// </summary>
	public static IUnityContainer GetConfiguredContainer()
	{
		return container.Value;
	}
	#endregion

	/// <summary>Registers the type mappings with the Unity container.</summary>
	/// <param name="container">The unity container to configure.</param>
	/// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
	/// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
	public static void RegisterTypes(IUnityContainer container)
	{
		// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
		// container.LoadConfiguration();

		// TODO: Register your types here
		container.RegisterType<ILog, LogFile>();
	}
}

Ahora si podemos ejecutar la aplicación, y en este caso podemos ver que la dependencia se resuelve correctamente:

unity II - img II

Espero les haya gustado el post, en el siguente post ya vamos a entrar más en detalle en otras características de Unity!

Y no te olvides compartir el post!

Un comentario sobre “[C#] Microsoft Unity II – Iniciando con Unity

    […] Microsoft Unity II – Iniciando con Unity […]

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s