Windows Communication Foundation nos permite desarrollar servicios en .Net de una manera rápida y sencilla, permitiendo soportar varios endpoints y esquemas de configuración. También ofrece un gran nivel de personalización, uno de ellos es poder escribir OperationBehaviors personalizados para nuestro servicio.
Un OperationBehavior nos permite cambiar y controlar el modo en que WCF ejecuta un método, por ejemplo podemos ejecutar código automáticamente antes de que se llame a una operación o después. Este es el caso que veremos en el siguiente ejemplo:
Creación del Servicio
Ok manos a la obra, lo primero es crear un nuevo proyecto WCF, el cual llamaremos “CalculatorService”
Luego agregamos dos operaciones a nuestro servicio, tanto en la interfaz como en la implementación: Add y Substract, como se ve en la siguiente figura:
Estas dos funciones lo que hacen es agregar y restar un valor de la variable de instancia _currentValue.
Ejecutamos el proyecto, y Visual Studio abrirá un cliente básico para poder probar nuestro servicio:
Behaviors
Ahora haremos algo interesante: Cada vez que se llame al método Add o Substract invocaremos de forma automática a un tercer método llamado “Audit”, esto lo hacemos usando OperationBehviors que nos permitirá tener acceso a personalizar la invocación de nuestros métodos.
En el proyecto de nuestro servicio WCF creamos una nueva carpeta llamada Behaviors ya agregamos una nueva clase llamada “MyOperationBehavior.cs” con el siguiente código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace CalculatorService.Behaviors
{
public class MyOperationBehavior : Attribute, IOperationBehavior
{
#region IOperationBehavior Members
public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
{
}
public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
{
// Decorator pattern.
dispatchOperation.Invoker = new MyOperationInvoker(dispatchOperation);
}
public void Validate(OperationDescription operationDescription)
{
}
#endregion
}
class MyOperationInvoker : IOperationInvoker
{
private readonly IOperationInvoker _invoker;
private readonly System.ServiceModel.Dispatcher.DispatchOperation _dispatchOperation;
public MyOperationInvoker(System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
{
this._invoker = dispatchOperation.Invoker;
this._dispatchOperation = dispatchOperation;
}
private void HandleOperationRequest(object instance, object[] inputs)
{
Service1 srv = (Service1)instance;
srv.Audit(_dispatchOperation.Name, inputs);
}
#region IOperationInvoker Members
public object[] AllocateInputs()
{
return _invoker.AllocateInputs();
}
public object Invoke(object instance, object[] inputs, out object[] outputs)
{
HandleOperationRequest(instance, inputs);
return _invoker.Invoke(instance, inputs, out outputs);
}
public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
{
HandleOperationRequest(instance, inputs);
return _invoker.InvokeBegin(instance, inputs, callback, state);
}
public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
{
return _invoker.InvokeEnd(instance, out outputs, result);
}
public bool IsSynchronous
{
get { return _invoker.IsSynchronous; }
}
#endregion
}
}
Ahora decoramos nuestros métodos Add y Substract con el atributo anterior y creamos el método “Audit”:
Lo que hemos hecho hasta el momento es crear una clase MyOperationBehavior que se encarga de conectar el MyOperationInvoker al servicio. Al aplicar el atributo [MyOperationBehavior] en cada operación hacemos que WCF use nuestro Operation Invoker para llamar a las respectivas funciones.
Dentro de MyOperationInvoker estamos llamando primero al método Audit para imprimir en pantalla la operación que el usuario está a punto de ejecutar.
Esto nos da el control de poder ejecutar código adicional antes de que se ejecute el método que invocó el cliente (o incluso desués). Si volvemos a ejecutar el servicio podemos ver los resultados en la ventana “Output” de Visual Studio 2010.
Nota: Este mismo resultado se pudo obtener llamando desde los métodos Add y Substract al método Audit. Pero gracias a los OperationBehaviors podemos remover esta lógica de cada posible método que tengamos y ponerla en un solo lugar.










