2. Enterprise Library
Conjunto de librerías open-source que facilitan el desarrollo
de aplicaciones empresariales .Net
Implementan funcionalidad habitual
Utilizando buenas prácticas de programación
Microsoft Patterns & Practices
http://entlib.codeplex.com/
Se basa en ficheros de configuración
App.config y Web.config
Incluye mecanismos de extensión mediante Interfaces y
Clases Base
Se distribuye como ejecutable con plug-in para Visual Studio
5. Configuration Application Block
Eje central de EntLib
Permite acceder a ficheros de configuración
App.config y Web.config
Metadatos
Proveedor de datos de configuración
Configuración propia del proveedor
Transformador opcional
Objetos
ConfigurationManager
ConfigurationBuilder
IStorageProviderReader/Writer
ITransformer
6. Configuration Application Block
Ejemplo: Usuario
Usuario
Nombre
Dada una clase de entidad Usuario Edad
Crear una fachada de configuración FechaNacimiento
Pais
Abstracta de métodos estáticos
Microsoft.Practices.EnterpriseLibrary. Configuration.
Configuracion
ConfigurationManager VerUsuario()
Guardar(Usuario)
GetConfiguration y WriteConfiguration
Crear un formulario para introducir los datos
Crear otro formulario que los muestre
Configurar app.config
8. Validation Application Block
Microsoft.Practices.EnterpriseLibrary.Validation.dll
Lógica de validación
Reglas de validación comunes encapsuladas en clases
reutilizables
Tamaño de string, rango de un numero, fecha, expresión regular,…
Que heredan de la clase Validator
MessageTemplate indica el mensaje de error
Negated valida lo contrario
Tag permite etiquetar validadores para agrupar mensajes x ej.
Incluye conectores para automatizar la validación de
controles de formularios
Windows Forms, ASP.NET y WCF
9. Validation Application Block
Reglas de validación (heredadas de Validator)
Not Null
Range Validator
Date Time Range
Relative Date Time (respecto a hoy)
Domain (conjunto de valores)
String Length
Regular Expression
Contains Characters
Enum Conversion (de string a tipo enumerado)
Type Conversion (de string a un tipo dado)
Property Comparison
Object Validator (el objeto contenido en una propiedad)
Object Collection (los objetos en una propiedad colección/array)
And/Or Composite
10. Validation Application Block
Uso de los validadores
Mediante código
Instanciar el validador e invocar su método Validate()
Poco utilizado, es más fácil con C#
Mediante propiedades
Etiquetar las propiedades legibles con el validador
[NotNullValidator(MessageTemplate="Error!!")]
[StringLengthValidator(1, 50)]
public string Nombre {get; set;}
Mediante archivos App.config y Web.config
EntLibConfig.exe
Mediante autovalidación
Crear una clase con un método de validación
[HasSelfValidation] public class MiClase {...}
[SelfValidation] public void Metodo(ValidationResults r) {...}
11. Validation Application Block
Plantillas de mensajes
Se puede utilizar MessageTemplate con tokens
{0} representa el objeto que se valida
{1} representa el elemento a validar
{2} representa la propiedad Tag del validador
{3} representa el primer parámetro del validador
Ejemplo
[StringLengthValidator(5, RangeBoundaryType.
Inclusive, 20, RangeBoundaryType.Inclusive,
MessageTemplate = "[{0}]Name debe tener {3} a
{5} caracteres")]
public String Descripcion;
Mostrará “Descripcion debe tener 5 a 20 caracteres”
12. Validation Application Block
Conjuntos de Reglas (Ruleset)
Definidos en el fichero .config o como parámetro del validador
Permiten añadir distintas validaciones
Ejecutar la validación
ValidationResults results = Validation.Validate<Cliente>
(cli);
Validation.Validate<Cliente>(cli, "rulesetA", "rulesetB");
Validator<Cliente> validator =
ValidationFactory.CreateValidator<Cliente>();
ValidationResult
Contenido en el ValidationResults
Propiedades: Message, Target, Validator, NestedValidationResults,…
Validación en formularios
Win Forms: Mediante el control ValidationProvider
ASP.NET: Mediante el control PropertyProxyValidator
13. Validation Application Block
Ejemplo 4.0
public class Cliente{
[NotNullValidator()]
[StringLengthValidator(1, 50)]
public string Nombre{ get; set; }
[RegexValidator(@"w+([-+.']w+)*@w+([-.]w+)*.w+([-.]w+)*",
MessageTemplate = "e-mail incorrecto")]
public string Email{ get; set; }
}
//
// En otro método de otra clase
//
Cliente cli = new Cliente{Nombre="Oliver", Email="oliver@curso.com"};
ValidationResults results = Validation.Validate<Cliente>(cli);
if(!results.IsValid){
MessageBox.Show("Error al crear el cliente");
return;
}
16. Caching Application Block
Implementación de un sistema de caching con políticas de
recolección y expiración
Se encarga de mantener sincronizada la cache en memoria y
la copia almacenada
Evita consultas repetitivas de los datos
Mejora la escalabilidad y la disponibilidad
Permite indicar políticas de expiración
Invalidar objetos tras un tiempo sin usarse
Tiempo absoluto, móvil, extendido y dependiente de archivo
Permite indicar un máximo de objetos en caché
Al llegar al máximo se elimina un número concreto
Se ordenan los objetos por prioridad y última hora de acceso
17. Caching Application Block
Ejemplo 4.0
Obtener una instancia de caché (singleton)
ICacheManager cache = CacheFactory.
GetCacheManager();
Añadir objetos a caché
Persona p = new Persona();
cache.Add("manolo", p);
Se puede indicar una prioridad y una expiración
cache.Add("manolo", p, CacheItemPriority.Normal,
null, new SlidingTime(TimeSpan.FromMinutes(5)));
Eliminar objetos de chaché
cache.Remove("manolo");
cache.Flush();
18. Caching Application Block
Callback
Se dispara al eliminar un objeto de caché
Permite recoger el evento en ICacheItemRefreshAction
Persistencia
Se puede persistir la caché en SQL Server y en almacenamiento
aislado
Configuración mediante App.config y Web.config
ExpirationPollFrequencyInSeconds
MaximumElementsInCacheBeforeScavenging
NumberToRemoveWhenScavenging
System.Web.Caching
Implementación de caché para ASP.NET
Recomendado usar este en lugar de Caching App Block
19. Caching Application Block
Ejemplo 5.0
Obtener una instancia de caché (singleton)
ICacheManager cache = EnterpriseLibraryContainer.
Current.GetInstance< ICacheManager>();
Obtener una instancia de persistencia
ICacheManager cacheP = EnterpriseLibraryContainer.
Current.GetInstance< ICacheManager>("almacen");
Extraer objetos de caché
if(cache.Count > 0 && cache.Contains("manolo")){
object o = cache.GetItem("manolo");
if(o != null)
Persona p = (Persona) o;
}
20. Caching Application Block
Ventajas de Caching Application Block
Permite persistencia del cache
Es posible mantener múltiples instancias de cache
independientes identificables por nombre
Se puede configurar a través del archivo de configuración
sin necesidad de recompilar la aplicación
Es extensible, se pueden implementar nuevas
Políticas de expiración (implementar ICacheItemExpiration)
Medios de almacenamiento
23. Security Application Block
Autorización
Determinar si un usuario tiene acceso a un recurso
Interfaz IAuthorizationProvider con método Authorize()
Proveedores de autorización que definen reglas
Authorization Manager (AzMan)
Authorization Rule Provider (Archivo de configuración)
Caching de credenciales
Evita autenticar al usuario en cada invocación
Se genera un ticket que se entrega a la aplicación cliente
Se puede almacenar
Un objeto IIdentity con la identificación de usuario
Un objeto IPrincipal con los roles a los que pertenece
Un objeto Profile con información adicional acerca del usuario
24. Security Application Block
Configurar AzMan
Herramienta para acceder a Active Directory y otros almacenes de
usuarios y roles
Permite administrar reglas de seguridad en estas ubicaciones
Aplication: Nombre de la aplicación
AuditIndentifierPrefix: Prefijo que antecede el identificador de
auditoria
Scope: El ámbito de autorización
StoreLocation: El lugar donde están almacenadas las reglas
Archivo XML
Active Directory
Base de Datos
25. Security Application Block
Configurar AuthorizationRuleProvider
Fichero de configuración (App.config/Web.config)
Crear un proveedor de reglas
Crear una regla (Acción)
Indicar la expresión que valida la regla
R:Grupo para indicar pertenencia a un rol
I:Usuario para indicar identidad de un usuario
Un editor permite validar las expresiones
Se pueden crear varias reglas de validación
26. Security Application Block
Configurar Caché de Credenciales
Fichero de configuración (App.config/Web.config)
Crear un proveedor de seguridad
Indicar el tiempo en minutos que se mantendrá una identidad en caché
AbsoluteExpiration
Indicar un tiempo móvil de expiración también en minutos
SlidingExpiration
Configurar e indicar el manejador de caché
Se pueden crear varios proveedores de caché
27. Security Application Block
Ejemplo de autorización 4.0
Obtener un proveedor de autorización
IAuthorizationProvider proveedor = AuthorizationFactory.
GetAuthorizationProvider("MiProveedor");
Determinar las credenciales (principal) a autorizar
IPrincipal ppal = new GenericPrincipal(
new GenericIdentity("usuario"), // usuario
new string[]{"Administrador"}); // roles
Determinar si el usuario está autorizado para ejecutar una acción
bool autorizado = proveedor.Authorize(ppal, "Acción");
Detalles
Si usamos AzMan la acción representa operaciones
Si usamos Rule Provider la acción representa el nombre de una regla
28. Security Application Block
Ejemplo de caché de credenciales 4.0
Obtener un proveedor de caching
ISecurityCacheProvider cache = SecurityCacheFactory.
GetSecurityCacheProvider("Proveedor");
Guardar la identidad del usuario y obtener su ticket
De manera similar se puede guardar las credenciales o el perfil
IToken ticket = cache.SaveIdentity(
new GenericIdentity("usuario"));
Recuperar la identidad del usuario
IIdentity miIdentidad = cache.GetIdentity(ticket);
Eliminar una identidad de la caché
cache.ExpireIdentity(ticket);
29. Security Application Block
Ejemplos 5.0
Obtener un proveedor de autorización
IAuthorizationProvider proveedor =
EnterpriseLibraryContainer.Current.
GetInstance<IAuthorizationProvider>("ProveedorAuth");
Obtener un proveedor de caching
ISecurityCacheProvider cache =
EnterpriseLibraryContainer.Current.
GetInstance<ISecurityCacheProvider>("ProveedorCache");
Obtener la identidad de Windows del usuario
WindowsIdentity wi = WindowsIdentity.GetCurrent();
Guardo la identidad y obtengo el ticket
IToken ticket = cache.SaveIdentity(wi);
30. Security Application Block
Ventajas de Security Appication Block
Reduce la necesidad de escribir código repetitivo
Evita tener que aprender a usar diferentes
implementaciones de autorización
La funcionalidad de autorización queda desacoplada
La forma que se realiza la autorización es consistente a
pesar que se utilicen diferentes implementaciones
Es extensible (extender AuthorizationProvider)
[ConfigurationElementType( typeof
(CustomAuthorizationProviderData))]
Se integra con Policy Injection Application Block y Unity
Application Block
32. Cryptography Application Block
Interfaz única que permite realizar encriptación y hashing de
datos con diversos algoritmos de clave simétrica
Incluye un sistema para administrar y distribuir las claves de
encriptación (archivos de transporte)
Protegiéndolas con una contraseña personalizada
A través de un Wizard de exportación/importación
4 métodos estáticos de criptografía
CreateHash()
CompareHash()
EncryptSymmetric()
DecryptSymmetric()
Trabajan con parámetros String o byte[]
Hay que serializar los objetos a byte[]
SerializationUtility.ToBytes(objeto)
33. Cryptography Application Block
Algoritmos de clave simétrica
Las 2 partes de la comunicación usan la misma clave
Cryptography Application Block la protege con
encriptación DPAPI
Encriptada con la contraseña de la cuenta de usuario
Encriptada a nivel de equipo
Cryptography Application Block permite distintas claves
Nueva escrita por el usuario
Nueva generada aleatoriamente
Existente creada previamente
Importada de un archivo de transporte
Guarda la clave en un archivo local
34. Cryptography Application Block
Ejemplo 4.0
Encriptar un valor String con un algoritmo dado
string encriptado = Cryptographer.
EncryptSymmetric("algoritmo", valor);
Desencriptar un contenido encriptado
string valor = Cryptographer.
DecryptSymmetric("algoritmo", encriptado);
Generar una clave Hash para un valor
string hash = Cryptographer.CreateHash("algoritmo",
valor);
Validar un Hash contra un valor dado
bool valido = Cryptographer.CompareHash("algoritmo",
valor, hash);
35. Cryptography Application Block
Ejemplo 5.0
Crear un manejador de criptografía
CryptographyManager cm = EnterpriseLibraryContainer.
Current.
GetInstance<CryptographyManager>();
Encriptar un valor byte[] con un algoritmo dado
byte[] serializado = SerializationUtility.ToBytes(objeto);
byte[] encriptado = cm.
EncryptSymmetric("algoritmo", serializado);
Desencriptar un byte[] encriptado
byte[] valor = cm.
DecryptSymmetric("algoritmo", encriptado);
Detalles
Liberar la memoria lo antes posible para evitar agujeros de seguridad
Se recomiendan los algoritmos SHA para hashing y AES para
encriptación
36. Cryptography Application Block
Ventajas de Cryptography Application Block
Soporta diversos algoritmos de hashing y encriptación
Abstrae el código que requiere cada algoritmo y presenta una Interfaz
sencilla con solo cuatro métodos
Evita tener que aprender código especifico para cada algoritmo
Consistencia en la manera en que se realizan las tareas de criptografía
dentro de un proyecto, o incluso dentro de toda la compañía
Se puede modificar un algoritmo editando el archivo de configuración
sin necesidad de recompilar la aplicación
Es extensible
Incluye un mecanismo para almacenar las claves y transportarlas de
manera segura
38. Exception Handling Application Block
Manejo de Excepciones
Tratar de recuperarse de la excepción, por ejemplo reintentando la
operación
Ejecutar código de limpieza
Mostrar un mensaje de error al usuario
Registrar la excepción en el log para posterior diagnostico
Notificar la excepción para que no pase inadvertida, por ejemplo vía
email o un evento WMI
Reemplazar la excepción por otra de mas alto nivel para evitar que se
filtre información por razones de privacidad o seguridad
Envolver la excepción inicial con una mas significativa para entregar
una mejor información de contexto sin perder los detalles de la
excepción origina
39. Exception Handling Application Block
Permite simplificar y estructurar el manejo de excepciones
La cláusula catch delega el manejo de la excepción al bloque
Indicando una política de excepción
Se configuran las políticas en App.config/Web.config
Manejadores (handlers) encapsulan el tratamientos
Logging de la excepción
Reemplazar la excepción (replace)
Envolver la excepción (wrap)
Métodos para la gestión de una excepción
HandleException(ex, "Política")
Process(delegado, "Política")
40. Exception Handling Application Block
Ejemplo:
Crear la política de excepción
Definir los tipos de excepción tratados
Para cada tipo definir los manejadores (handlers)
Para cada tipo definir el PostHandlingAction
Acción tras ejecutar todos los manejadores
ThrowNewException, NotifyRethrow, None
Si la excepción no encaja con ningún tipo se relanzará
Invocar al manejador dentro de la cláusula catch
Devuelve true si hay que relanzar la excepción
bool relanzar = ExceptionPolicy.
HandleException(ex, "Politica");
Detalles
Se recomienda definir las políticas como constantes
41. Exception Handling Application Block
Ejemplo 5.0:
Creo el manejador de excepciones
ExceptionManager gestor = EnterpriseLibraryContainer.
Current.GetInstance<ExceptionManager>();
Ejecuto un método de manera segura
gestor.Process(metodo, "PoliticaProteccion");
Ejecuto un método anónimo
gestor.Process(() => {
// código
},
"PoliticaProteccion");
Ejecuto un método con parámetros
gestor.Process(() => metodo(param1, param2),
valorDeRetornoPorDefecto,
"PoliticaProteccion");
42. Exception Handling Application Block
Configuración de manejadores:
Se disparan en cadena, el orden es MUY importante
Replace Handler
Evita que se filtren datos privados o código inferior
Indicar el nuevo mensaje de error en ExceptionMessage
Indicar la nueva excepción en ReplaceExceptionType
Wrap Handler
Envuelve la excepción con otra más significativa
Indicar la nueva excepción en WrapExceptionType
Logging Handler
Registra la excepción contra el Logging Application Block
43. Exception Handling Application Block
Ventajas de Exception Handling Application Block
Encapsula la lógica de manejo de excepciones en clases reutilizables
(handlers)
Permite definir políticas de manejo de excepciones aplicables a un
gran numero de métodos
Se puede modificar las políticas sin recompilar la aplicación
El programador solo escribe código estándar en la cláusula catch
indicando el nombre de una política, el arquitecto define que hace
cada política en el archivo de configuración
Se puede integrar con Policy Injection Application Block para separar
el manejo de excepciones de la lógica de la aplicación haciendo
innecesaria la cláusula catch
Es extensible
Implementando IExceptionHandler
[ConfigurationElementType(typeof(CustomHandlerData))]
45. Data Access Application Block
Facilita el uso de ADO.NET
Interfaz con métodos simples para las tareas mas comunes de
acceso a datos
Llenar y actualizar un DataSet
Leer varios DataRow
Crear un Command
Ejecutar un Command
Parametrizar un Command
Obtener datos XML
Obtener datos como secuencia de objetos
Trabajar con transacciones
Permite escribir código agnóstico compatible con múltiples
bases de datos
46. Data Access Application Block
Configurar la Base de Datos
Indicar el <connectionString> en App.config/Web.config
Indicar el proveedor de datos
Instanciar la Base de Datos
Database bd = EnterpriseLibraryContainer. Current.
GetInstance<Database>("cadena");
Obtener un Command
DbCommand sqlCmd = bd.GetSqlStringCommand(sql);
Obtener un Reader
IDataReader reader = bd.ExecuteReader(
CommandType.Text, sql);
Obtener datos como XML
XmlReader reader = bd.ExecuteXmlReader(xmlCmd);
reader.ReadOuterXml();
47. Data Access Application Block
Trabajo con DataSets
DataSet ds = bd.ExecuteDataSet(sqlCmd);
bd.LoadDataSet(CommandType.Text, sql, ds,
new String[]{"TablaDS"});
// Insertar y actualizar (parámetros nuevos)
bd.AddInParameter(sql, "paramSQL", DbType.String,
"ColumnaDS", DataRowVersion.Current);
// Eliminar (parámetros originales)
bd.AddInParameter(sql, "paramSQL", DbType.String,
"ColumnaDS", DataRowVersion.Original);
// Ejecutar la actualziación
int filas = bd.UpdateDataSet(ds, "TablaDS", sqlInsert,
sqlUpdate, sqlDelete, UpdateBehavior.Standart);
48. Data Access Application Block
Trabajo con Transacciones
DbConnection conexion = bd.CreateConnection();
conexion.Open();
DbTransaction tx = conexión.BeginTransaction();
tx.Commit();
tx.Rollback();
Trabajo con Objetos
var datos = bd.ExecuteSprocAccessor<Clase>(sql);
Mapeadores de Objetos
Cuando los campos no encajan con las columnas
IRowMapper<Clase> map = MapBuilder<Clase>
.MapAllProperties()
.Map(x => x.Propiedad).ToColumn("columna")
.Map(x => x.Propiedad).WithFunction(fila => { ... })
.Build();
var datos = bd.ExecuteSprocAccessor<Clase>(sql, map);
50. Logging Application Block
Implementa logging a diferentes destinos
Registro de eventos, archivo de texto, BD, eMail, MSMQ, WMI,…
Es posible configurar
Categorías
Propiedades AutoFlush y MinimumSeverity
Múltiples destinos
Listeners que se configuran para hacer log a un destino
Filtros
SeverityFilter para cada Listener de una categoría
LoggingFilters para filtrar por categorías o prioridad
Formatos
FormatterName para cada Listener de una categoría
Editor de plantillas para formatos
51. Logging Application Block
Ejemplo
Obtener un escritor de Log
LogWriter log = EnterpriseLibraryContainer. Current.
GetInstance<LogWriter>();
Escribir en el log
log.Write("Mensaje");
log.Write("Mensaje", new string[]{"Categoría"});
log.Write("Mensaje con categoría, prioridad, evento
y severidad", "Categoría", 6, 9001,
TraceEventType.Warning);
Por defecto Category = General, Priority = -1, Event ID =
1 y Severity = Information
Por defecto la categoría General vuelca en Windows
Application Event Log
52. Logging Application Block
Información de contexto
Se obtiene la información en un diccionario
Dictionary<string, object> dict = new
Dictionary<string, object>();
// Información de depuración
new DebugInformationProvider()
.PopulateDictionary(dict);
// Información de seguridad
new ManagedSecurityContextInformationProvider()
.PopulateDictionary(dict);
new UnmanagedSecurityContextInformationProvider()
.PopulateDictionary(dict);
// Otra información
string config = File.ReadAllText(@"....App.config");
dict.Add("Configuración", config);
53. Logging Application Block
Log Entry
Clase de soporte de logs
Permite añadir varias entradas
LogEntry entry = new LogEntry("Mensaje con
categoría, prioridad, evento y severidad",
"Categoría", 6, 9001, TraceEventType.Warning);
log.Write(entry);
Permite añadir información de contexto
entry.ExtendedProperties = dict;
log.Write(entry);
55. Unity Application Block
Características
Soporta inyección de constructores, propiedades y métodos
La inyección de constructores es automática, no requiere atributos o
configuración
La inyección de propiedades y métodos requiere atributos o
configuración
Puede utilizarse como un contenedor jerárquico
El contenedor puede crear clases concretas no incluidas en el mapeo
del contenedor
Puede usarse el estilo de interfaz fluida (fluent interface) para
configurar el contenedor
El contenedor puede ser extendido
Soporta intercepción
57. Unity Application Block
Utilización
Crear el contenedor
IUnityContainer unity = new UnityContainer();
Definir las dependencias
[Dependency] public IClase Campo{ get;set; }
Definir los métodos inyectables
[InjectionMethod] public void Metodo(){
[InjectionConstructor] public Clase(){
Resolver instancias
Clase instancia = unity.Resolve<Clase>("nombre");
new InjectionProperty("nombre");
new InjectionConstructor("nombre");
new ResolvedParameter<Clase>("nombre");
58. Policy Injection Application Block
Programación Orientada a Aspectos
Mecanismo de intercepción para extender métodos y
propiedades sin modificar el código fuente
Incorporar funcionalidad transversal
log, autorización, instrumentación, transacciones, caching
Políticas definidas en el archivo de configuración
Mediante wildcards
A qué métodos y propiedades se aplicará
Reemplazado por Unity
Notas del editor
ConfigurationManager : no es más que una fachada estática para leer y escribir configuración desde una porción determinada. En un plano más terrenal, consiste en un objeto que dispone de los métodos adecuados para leer porciones de la configuración. Estos metodos leen la "metadata" de la configuración para saber dónde obtener la porción de configuración que se solicita; para esto consume una instancia del ConfigurationBuilder , el cual le devuelve ya "masajeado" un objeto en donde reside la configuración. Estos objetos actúan a modo de transporte y son definidos según la configuración. ConfigurationBuilder : es un objeto encargado de crear el proveedor de configuración, leer la configuración y transformarla en objetos que el configurationManager entienda. Es decir, instancia un objeto que implemente las interfaces de lectura/escritura de configuración, lee dicha configuración y popula los objetos que hayamos determinado para transportarla hasta el manager. IStorageProviderReader/Writer : representa la interfaz que deberá implementar el proveedor que se ocupa de leer y escribir la configuración en un repositorio determinado, ya sea éste un XML, SQL, etc. El bloque cuenta con un proveedor específico para XML similar al que cuenta nativamente .net para sus configuraciones base. Este es XmlFileStorageProvider , el cual implementa ambas interfaces. ITransformer : es la interfaz predeterminada que deberá implementar un proveedor de transformación; esto es una clase que tenga la habilidad de convertir o desconvertir los seteos de configuración en objetos tipados que la aplicación cliente "entienda". El bloque dispone de un proveedor XmlSerializerTransformer que implementa dicha interfaz. Este proveedor transforma nodos XML (XmlNode) a objetos y viceversa. Si bien no es necesario transformar los datos recibidos del repositorio en objetos tipados ya que se puede trabajar directamente con los objetos devuelvos por el repositorio, es una buena práctica implementar esta transformación.
Obtener datos como objetos var datos = bd.ExecuteSprocAccessor< Clase >(sql); Mapeadores de Objetos