Una de las ventajas de utilizar un contenedor como Windsor container es la capacidad que nos proporciona para interceptar llamadas a métodos.

Supongamos que tenemos un sistema que se dedica a esperar a la recepción de un mensaje y que está implementado por la clase Receiver.

public class Receiver{
    public void WaitMessages()
    {
        while (true)
        {
            Console.Write("Escriba un mensaje: ");
            string message = Console.ReadLine();
            if (message == "exit" || message == "quit")
                break;
            OnMessageReceived(message);
        }
    }

    protected virtual void OnMessageReceived(string message)
    {
        Console.WriteLine("Mensaje recibido: " + message);
    }
}

El receptor espera a que le llegue un mensaje y una vez recibido llama al método OnMessageReceived, que se encarga de procesar el mensaje y que típicamente podría generar un evento informando a otras partes del sistema de la recepción de un mensaje.

Ahora imaginemos que por razones de seguridad queremos supervisar los mensajes que lleguen y dar nuestra aprobación para que dichos mensajes se transmitan.

Una opción sería modificar la clase Receiver con la lógica necesaria para implementar el nuevo sistema de seguridad, sin embargo, dicha clase puede ser bastante compleja ya de por si y además, puede que deseemos reutilizar dicha clase en otras partes que no requieran tan estricto control de seguridad.

La interceptación de métodos nos proporciona una opción sin duda más conveniente para este caso. Generamos una clase, que llamaremos ParentalControlInterceptor la cual implementa el interface IInterceptor.

public class ParentalControlInterceptor: IInterceptor{
    #region IInterceptor Members

    public void Intercept(IInvocation invocation)
    {
        if (invocation.Method.Name == "OnMessageReceived")
        {
            Console.WriteLine("Mensaje interceptado: " + invocation.Arguments[0].ToString());
            Console.Write("¿Aprueba el envío de este mensage (s/n)?");
            string response = Console.ReadLine();
            if (response.ToUpper().StartsWith("S"))
                invocation.Proceed();
        }
    }

    #endregion}

En dicha clase comprobamos si el nombre del método interceptado coincide con el que nos interesa, en este caso es OnMessageReceived, y en caso afirmativo preguntamos si se desea aprobar la retransmisión del mensaje. El método OnMessageReceived de nuestra instancia de Receiver solo será invocado en el caso de que se apruebe la retransmisión.

Por último, para que los métodos de nuestro receptor sean interceptados todo lo que tenemos que hacer es decorar la clase con el atributo Interceptor tal y como se muestra a continuación.

[Interceptor(typeof(ParentalControlInterceptor))]
public class Receiver{
    public void WaitMessages()
    {
        while (true)
        {
            Console.Write("Escriba un mensaje: ");
            string message = Console.ReadLine();
            if (message == "exit" || message == "quit")
                break;
            OnMessageReceived(message);
        }
    }

    protected virtual void OnMessageReceived(string message)
    {
        Console.WriteLine("Mensaje recibido: " + message);
    }
}

Actualmente, para que la interceptación se produzca es un requisito que, o bien se registre el componente en el contenedor con un interface o bien que los métodos a interceptar sean marcados como virtuales.

En la siguiente figura se observan los resultados que produce la interceptación tanto en el caso de que un mensaje se apruebe como en el contrario.

Resultados de la interceptación