En el Enterprise Library 3.0 (CTP de Febrero 2007) han incluido a última hora un nuevo Application Block llamado Policy Injection Application Block.
Este application block permite definir políticas a métodos y objetos de forma declarativa.
Cada política contiene una serie de handlers que son ejecutados antes y después del método que tenga las políticas habilitadas. Las acciones a realizar por estas políticas serán Validaciones, Logging, manejo de excepciones, etc.
En la creación del objeto usaremos una clase Factory que será la encargada de inspeccionar el fichero de configuración de la aplicación y aplicar las políticas que hayamos definido en este.
Ejemplo de creación de un objeto:
Transferencias objTrans = PolicyInjection.Create<Transferencias>();
Aquí radica la principal potencia de este Application Block, que no tenemos que modificar nuestro código para poder modificar las políticas, ya que estas son definidas de forma declarativa en un fichero de configuración y se aplican en tiempo de ejecución.
Dentro del fichero de configuración vamos a tener un formato parecido al siguiente:
<policies>
<add name="PolicyName">
<matchingRules>
Aquí vamos a tener la lista de reglas que se deben validar antes de aplicar la política
</matchingRules>
<handlers>
Aquí vamos a tener la lista de handlers que ejecutará esta política
</handlers>
</add>
</policies>
La siguiente pregunta es, ¿Qué tiene que cumplir mi clase para poder se “interceptada” por este aplication block?:
Tenemos dos opciones:
· Declarar un interface del cual herede nuestra clase.
· Crear una clase que herede de MarshalByRefObject.
Ejemplo:
namespace DemoPolicyInjection
{
public class Transferencias: MarshalByRefObject
{
public void Transferencia(string numCuenta1, string numCuenta2)
{
//Código a implementar en el método
}
public void TransferenciaError(string numCuenta1, string numCuenta2)
{
//Código a implementar en el método
}
}
}
Imaginémonos que queremos grabar en un log todas las llamadas que reciba cualquier método de esta clase. Para ello debemos usar el siguiente xml:
<policyInjection>
<policies>
<add name="SaveToLog">
<matchingRules>
<add name="Tipo Transaferencias" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.TypeMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=2.9.9.2" ignoreCase="false" match="Transferencias" />
</matchingRules>
<handlers>
<add name="Politica Grabar Log operaciones" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.LogCallHandler, Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers, Version=2.9.9.2" logBehavior="Before" beforeMessage="This is the before message" afterMessage="This is the after message" includeParameterValues="true" includeCallStack="true" includeCallTime="false" priority="42" severity="Information">
<categories>
<add name="LogOperaciones" />
</categories>
</add>
</handlers>
</add>
</policies>
</policyInjection>
Si analizamos el xml, vemos que para que se ejecute la política, el tipo del objeto debe ser Transferencias.
Cumplida esta condición se ejecuta el handler que en este caso graba en un fichero de log cada una de las llamadas que se hagan a cualquiera de los métodos de la clase Transferencia.
Los posibles valores que vamos a poder especificar en matchingRules son los siguientes:
- AssemblyMathingRule (todos los métodos de un assembly)
- CustomAttributeMatchingRule (todos los métodos que tengan un atributo el cual especificaremos)
- MemberNameMatchingRule (un método en concreto)
- MethodSignatureMatchingRule (una sobre carga en concreto de un método)
- NamespaceMatchingRule (todos los métodos de un namespace específico)
- ReturnTypeMatchingRule (todos los métodos con un valor de retorno específico)
- TagAttributeMatchingRule (todos los métodos con el atributo Tag)
- TypeMatchingRule (todos los métodos de un tipo específico)
Lista de Handlers en esta CTP:
- LogCallHandler
- ValidationCallHandler
- ExceptionHandlingCallhandler
Este post simplemente es una breve introducción de la potencia de este Application Blog. En el caso de que queráis profundizar mas, os recomiendo los siguientes post:
Adjunto un archivo con el código de ejemplo utilizado para este post: policyinjection.rar
En este ejemplo se usaran el Application Blog para grabar en un fichero de texto todas las llamadas a los métodos de la clase Transferencias. Además en el caso de que se produzcan un error en alguno de los métodos también se registrará en un log dicha excepción.
Los archivos de log se guadan en la misma ruta que el ejecutable y se llaman Trace.log y exception.log