Introducción a Inversión de Control (IOC)

jueves, 11 de septiembre de 2014


En el anterior post vimos una introducción a inyección de dependencias, en este vamos a ver una introducción a inversión de control pero a nivel de concepto, vamos a hacer un paréntesis en lo relacionado a DI. Una cosa es el concepto de inversión de control que no tiene porque estar relacionado con inyección de dependencias y otra diferente es un contenedor de inversión de control que es el nombre que reciben los contenedores relacionados con inyección de dependencias.


Introducción al concepto

El concepto de inversión de control fue introducido por Martin Fowler en 2005 en su artículo InversionOfControl.

Este método de programación es conocido como Principio de Hollywood, en referencia a la popular frase que suelen dar en las audiciones de actores, No nos llames, nosotros te llamaremos.

Es un estilo de programación donde el flujo de ejecución no es controlado por tu código, sino que es controlado por un componente externo, normalmente conocido como framework. Y es este framework el que invoca métodos o funciones definidos en tu código.

De hecho esta es una de las características para diferenciar entre libreria y framework. Una librería es un conjunto de métodos y funciones encapsuladas dentro de clases que son invocadas siempre desde nuestro código, llevando este el control sobre el flujo de ejecución. Sin embargo un framework es capaz de encargarse del flujo de ejecución de un proceso concreto y él se encarga de invocar nuestro código cuando lo necesita.

Ejemplo

Vamos a ver unos ejemplos de código donde estamos usando inversión de control y donde no lo estamos usando.

Ejemplo consola

Cuando trabajamos con un código de consola, el flujo ejecución es claramente controlado por nosotros.
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Inserta el número 1");

        int num1;

        bool isNumeric1 = int.TryParse(Console.ReadLine(), out num1);

        Console.WriteLine("Inserta el número 2");

        int num2;

        bool isNumeric2 = int.TryParse(Console.ReadLine(), out num2);

        if (isNumeric1 && isNumeric2)
            Console.WriteLine(string.Format("El resultado es {0} + {1} = {2}", num1, num2, num1 + num2));
            
        Console.ReadLine();

    }
}

Ejemplo winforms

Cuando trabajamos con un código de winforms, el flujo ejecución es controlado por el framework, nosotros lo único que hacemos es suscribirnos a un evento y es el framework el que invoca nuestro código.

El uso de eventos es una de las herramientas que se puede utilizar un framework para invocar nuestro código.
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void btnCalculate_Click(object sender, EventArgs e)
    {
        int num1;
        bool isNumeric1 = int.TryParse(txtNumber1.Text, out num1);

        int num2;
        bool isNumeric2 = int.TryParse(txtNumber2.Text, out num2);

        if (isNumeric1 && isNumeric2)
            MessageBox.Show(string.Format("El resultado es {0} + {1} = {2}", num1, num2, num1 + num2));
    }
}

Ejemplo test unitarios

Cuando trabajamos test unitarios es otro buen ejemplo de IOC, el flujo ejecución es controlado por el framework, nosotros lo único que hacemos definir nuestra clase de test unitario, métodos de test y métodos de inicialización, limpieza para clase, test etc.. decorando mediante atributos, pero el flujo de ejecución es controlado por el framework porque es quien invoca a nuestros métodos. Nosotros no decidimos cuando se invoca el método decorado con el atributo TestInitialize por ejemplo.
[TestClass]
public class UnitTest1
{
    public UnitTest1()
    {
    }

    private TestContext testContextInstance;

    public TestContext TestContext
    {
        get
        {
            return testContextInstance;
        }
        set
        {
            testContextInstance = value;
        }
    }

    [ClassInitialize()]
    public static void MyClassInitialize(TestContext testContext) { }

    [ClassCleanup()]
    public static void MyClassCleanup() { }

    [TestInitialize()]
    public void MyTestInitialize() { }

    [TestCleanup()]
    public void MyTestCleanup() { }


    [TestMethod]
    public void TestMethod1()
    {

    }
}

Resumen

Hemos visto en este artículo el concepto de inversión de control, el cual no tiene porque estar relacionado con inyección de dependencias. IOC se produce cuando el flujo de ejecución de un proceso concreto nos es gestionado por nosotros sino por un framework, además es una característica clave para identificarlo como framework y no librería.

En el siguiente post ya si que veremos inversión de control desde el enfoque de inyección de dependencias, pero me parecía interesante ver en este post simplemnete el concepto y ejemplos donde ya usamos IOC aunque no seamos conscientes.

Libros relacionados

Dependency Injection in .NET

No hay comentarios:

Publicar un comentario