Explotando el método "Find" de listas genéricas. Predicados y Delegados.

Recientemente, en uno de los comentarios añadidos al post Mejorando Nuestros DAO y DTO, se ha tratado el uso del método Find en listas genéricas.
Dejo a vuestra disposición dos artí­culos que marcan sendos ejemplos de uso. Resulta una práctica que puede seros interesante en vuestros desarrollos.
Link 1
Link 2
Saludos y gracias a Ignacio por el apunte.
Miguel.

AjaxControlToolkit y WebResource.axd

AjaxControlToolkit es el conjunto de controles web ajax provistos por el propio Microsoft y totalmente compatibles con Visual Studio 2008 y Framework 3.5 de .NET.
Hoy hablaremos brevemente cómo resolver la problemática que nos podemos encontrar si combinamos el uso de dicho Toolkit con la seguridad básica de ASP.NET.
Ante claíºsulas como la descrita en la parte inferior:
<authorization>
<deny users=”*” />
</authorization>
estamos denegando el acceso a cualquiera de los recursos de la aplicación, a todos los usuarios que no cuenten con cierto tipo de autenticación. Cuando hablamos de recursos estamos hablando de recursos de cualquier tipo, entre los cuales estamos incorporando páginas aspx, javascript, imágenes, hojas de estilo, themes…
Para resolver el acceso total a recursos necesarios a nivel de aplicación como por ejemplo hojas de estilo, imágenes y javascript podemos combiar el anterior tag con el siguiente:
<location path=”images”>
<authorization>
<allow users =”*” />
</authorization>
</location>
donde podemos apreciar cómo para todos los usuarios estamos dando acceso a la carpeta donde estamos almacenando las imágenes. Si no hiciéramos esto, las páginas aspx se cargarí­an, pero no podrí­amos ver las imágenes que tuviéramos contenidas.
Algo muy similar pasa cuando utilizamos Ajax Control Toolkit, vamos a necesitar indicar la visibilidad de sus recursos a los usuarios para que puedan ejecutar los controles ajax, tanto la funcionalidad javascript que incorporan como sus imágenes y estilos relacionados. Para ello, no tenemos que dar permisos a una carpeta concreta, si no a un fichero que no es visible en tiempo de diseño, pero que sí­ podremos observar si lanzamos la aplicación. Se trata del archivo WebResource.axd.
Añadiendo el nuevo location
<location path=”WebResource.axd”>
<authorization>
<allow users =”*” />
</authorization>
</location>
conseguiremos nuestro objetivo. Nuestros controles ajax volverán a funcionar correctamente, veremos las imágenes relacionadas a los controles, así­ como sus estilos.
Saludos.
Miguel.

Novedades Framework 3.5, Métodos de Extensión

Es curioso el siguiente nuevo mecanismo que aparece en el .NET Framework 3.5,
namespace MetodosExtension
{
  public static class MisExtensiones
  {
    public static bool ContieneLaZ(this String str)
    {
      //Código que a partir de un string retorna verdadero
      //si éste contiene la letra ‘Z’
    }
  }
}
Que luego te deja hacer cosas como esta;
string variable = “escuché un zumbido”;
if (variable.ContieneLaZ())
{
}
A esta nueva facilidad que incluye el entorno de desarrollo se le llaman extensiones. Como podréis apreciar lo que se ha hecho es definir en una clase separada un nuevo método asociado a un objeto (String) que el propio framework de .NET trae consigo. La magia para conseguir esto íºltimo reside en la forma en la que se define el parámetro del método “ContieneLaZ”, que como véis utiliza el identificador “this” previo a la definición de la variable y el tipo.
La principal gracia de todo esto es la capacidad de poder dotar de más potencia a clases ya definidas sin necesidad de utilizar tipos derivados y sin modificar el tipo original.
Apuntar además que las extensiones se mantienen también cuando heredamos la clase original sobre la que se ha hecho la extensión. Por ejemplo, si extendemos la clase “Coche” con nuevas operaciones, y luego creamos una clase “CocheVolador”, esta íºltima, también podrá contar con las extensiones definidas en su clase padre.
Saludos.
Miguel.

Solid RAD

Recientemente he tenido la oportunidad de participar en una presentación de Solid RAD, la herramienta para el desarrollo rápido de aplicaciones, ofrecida bajo el sello y garantí­a de calidad del equipo de Solid Quality Mentors
Jesíºs López y Daniel Seara (con el cual he tenido nuevamente el placer de coincidir) han sido los dos mentores de Solid que realizaron la presentación de forma conjunta.
A partir de la propia arquitectura y orientación de Solid RAD, la cual podréis conocer consultando el video provisto en el siguiente enlace mms://solidq.com/SolidRad (copiar el link y ejecutar pegando en la barra de dirección de Internet Explorer), destacar la inmensa oportunidad que supone compartir durante parte de una mañana, y de forma directa y personalizada, de los conocimientos y opiniones de los dos mentores. Lo que ha dado una pequeña “discusión” sobre el uso de las transacciones es algo que me gustarí­a exponer en un próximo artí­culo. A mi la visión me ha parecido genial.
Destacar entre otras cosas de Solid RAD, otras ideas fantásticas, como las de partir de un modelo de objetos de negocio para exponer el conocimiento a otras capas, pero sin orientar el modelo de objetos directamente a las entidades de datos, tal como harí­a un ORM, si no a las vistas definidas sobre dichas entidades de datos. Es una idea simplemente genial combiándola al mismo tiempo con el generador de código de Solid RAD, que automatiza la generación de las entidades de transporte de datos a partir de las propiedades de cada una de las vistas sobre la que es accedida.
Saludos.
Miguel.

Autenticación con AgilePoint y el uso de Surrogate

Una de las principales capacidades que ofrece AgilePoint como producto, es la orientación a servicios que han dado a la solución de software. Para ello, en la versión 4.0 de la herramienta ofrecen en concreto dos servicios que agrupan todos los métodos que permiten acceder a la funcionalidad del motor.
workflow.asmx
Servicio que encapsula todos los métodos asociados a la manipulación de los flujos (incluyendo por ejemplo servicios para instanciar plantillas, obtener información de un proceso, establecer el valor de una de las propiedades de un proceso…).
admin.asmx
Servicio que encapsula todos los métodos asociados a la administración del propio motor (incluyendo por ejemplo servicios especí­ficos para la creación de usuarios, permisos, roles…).
A priori, con estas dos piezas, y desde cualquier tipo de tecnologí­a cliente, podrí­amos manipular el BPM desde una aplicación cliente creada por nosotros mismos.
La pieza que aquí­ nos falta es conocer cómo se protege AgilePoint para que no todos los usuarios que tengan acceso a dichos asmx puedan utilizarlos para acceder al motor y manipularlo a su gusto. Como comprenderéis, si no existiera dicha autenticación estarí­amos hablado de un fallo de seguridad como la copa de un pino.
El requerimiento indispensable para poder acceder a los servicios, es que el mismo objeto que está realizando la conexión al servicio cuente con las credenciales de red del usuario que está haciendo la llamada. Esto ya en principio garantiza que la persona que está llamando al servicio está autenticada en el dominio, que quieras que no, supone una primera barrera de seguridad. Pero esto, no es suficiente, ya que necesitaremos que el usuario que esté haciendo la llamada también esté dado de alta en la propia base de datos de usuarios de Agilepoint. Como curiosidad, remarcar que la propia herramienta de gestión de usuarios de AgilePoint provee de facilidades para sincronizarse con el directorio activo e importar la información de los usuarios de dicho directorio a la base de datos de usuario de AgilePoint.
Resumiendo, si disponemos de nuestras credenciales de red validadas, se las pasamos a AgilePoint y nuestro usuario está también incluido en el repositorio de usuarios de AgilePoint, olé, ya podemos usar los servicios sin problemas.
Pongamos por ejemplo que estamos trabajando con una aplicación de escritorio que referencia los servicios web de AgilePoint directamente. Siguiendo este procedimiento, conseguiremos autenticarnos sin problema.
La casuí­stica complicada viene cuando por ejemplo trabajando en web, o en el caso de que no conectemos directamente con nuestra aplicación al servicio, si no que tengamos otra aplicación que haga la conexión en nuestro nombre. Estarí­amos hablando de una tí­pica aplicación web, donde el usuario que la está ejecutando es del del pool del servidor de aplicaciones y no la persona que ha abierto el navegador en su casa… o en el caso de que nuestra aplicación de servicios no ataque directamente a los servicios de AgilePoint si no que llame a una capa de negocio con orientación a servicios que sea la que se encargue después de llamar a Agilepoint. En ambos casos tenemos “algo”por enmedio que tiene sus propias credenciales que no son precisamente las nuestras.
Ante este problema tenemos una primera solución para lograr la autenticación, nos creamos un usuario para ese “algo” intermedio en nuestro directorio activo, lo damos de alta también en la base de datos de Agilepoint, y ala, cuando llamemos al “algo” este se podrá autenticar y hacer el trabajo sin problemas. Esto funciona, pero tiene un problema de base, que todos los usuarios trabajarán contra el BPM usando el mismo usuario, y esto va en contra del funcionamiento basado en flujos.
Como hemos tratado ya en otros artí­culos, uno de los componentes principales de un motor de flujo es el responsable de cada una de las tareas definidas en el flujo de trabajo. Parte de la gracia de este sistema de trabajo es que la persona que conoce el negocio define las responsabilidades de cada uno de los pasos a seguir, y a partir de esta responsabilidad, los usuarios asignados tendrán constancia de que tienen que realizar cada una de las tareas. Imaginaos entonces que siguiendo un flujo determinado se asigna la responsabilidad de las tareas generadas a una serie de usuarios. ¿Cómo voy a conseguir entonces preguntarle al motor de flujo que me de las tareas de dicho usuario especí­fico si siempre estoy haciendo login a través de un usuario intermedio comíºn a todos? En este caso todos serí­amos el mismo usuario y recibirí­amos siempre las mismas tareas.
Después de toda la puesta en situación inicial llegamos entonces al punto clave y objetivo del artí­culo, el Surrogate. Mediante la “surrogación” (no creo que esté este palabro en ningíºn diccionario) conseguimos decir en la autenticación que el usuario intermedio comíºn a todos hable en nombre de otro. Es decir, nos autenticamos igual, pero en un momento dado dicho usuario le dice a AgilePoint: “Oye tí­o, yo soy el que me autentico siempre, estas son mis credenciales y seguro que además me tienes en tu base de datos, y, a partir de ahora mismo todas las operaciones que voy a mandarte las voy a hacer en nombre de Pepe, por lo tanto, cuando te pida que me des todas las tareas en estado ofrecido me estoy refiriendo a las de Pepe, y cuando te diga que proceses una tarea lo vas a hacer también en nombre de Pepe”.
Claro está, “Pepe” va a tener que estar dado de alta en el repositorio de usuario de AgilePoint, o si no por mucho que le diga “el de siempre” que va a hablar en nombre de “Pepe”, AgilePoint va a responder: “no sé de quién me estás hablando”.
A partir de aquí­, para ver a nivel de código cómo funciona esto, os dejo un link de la página de Ascentn donde podéis ver el ejemplo:
Ejemplo KB-Ascentn
Para acabar, y como podréis ver en el link que os acabo de dejar, no todos los usuario disponibles en el repositorio de usuarios de AgilePoint tienen la capacidad de hablar en el nombre de otros. Para disponer de dicha capacidad, se debe dar de alta el usuario como “Impersonator” a través de la herramienta de configuración del servidor de AgilePoint.
Espero haberme explicado con suficiente claridad, no es precisamente fácil intentar trasladar el uso del Surrogate.
Saludos.
Miguel.

TableAdapters Transaccionales sin usar TransactionScope

La verdad es que el mundo de los TableAdapters y los Datasets Tipados abre muchí­simas puertas de cara a la productividad en el desarrollo y a la disminución de tasa de errores a la hora de trabajar contra una fuente de datos.
El problema que nos hemos encontrado muy amenudo es querer utilizarlos transaccionalmente pero sin emplear la herramienta TransactionScope de ADO.NET, y seguir utilizando una conexión y transacción controlada por nosotros mismos. No sé por qué pero en su dí­a intenté hacerlo así­ y no hubo manera y tuve que morir al palo del TransactionScope. Recientemente ha vuelto a surgir la necesidad, y, esta vez con Visual Studio 2008 y el Framework 3.5, parece que la cosa ha funcionado.
No sé si es cosa del Framework 3.5 (en su dí­a lo intenté con la versión 2.0), o que hoy me ha dado por estar líºcido, o las otras veces demasiado poco líºcido, pero hoy con una tonterí­a de código he conseguido trabajar de forma transaccional entre dos TableAdapters que están en dos Datasets distintos, compartiendo la misma conexión y transacción.
Sin más rodeos, el código:

public void InsertMarca(string marca, int veces)
{

SqlTransaction tran = null;
SqlConnection con = null;
try
{
// abrimos una conexión
con = new SqlConnection(“Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\BBDD.mdf;Integrated Security=True;User Instance=True”);
con.Open();
//establecemos que la conexión de la marca es la que hemos creado
MarcaTableAdapter adapterMarca = new MarcaTableAdapter();
adapterMarca.Connection = con;
// establecemos que la conexión del coche es la que hemos creado
CocheTableAdapter adapterCoche = new CocheTableAdapter();
adapterCoche.Connection = con;
// iniciamos una transacción sobre dicha conexión
tran = con.BeginTransaction();
// le pasamos a los adaptadores la transacción que acabamos de crear
adapterMarca.Transaction = tran;
adapterCoche.Transaction = tran;
for (int i = 0; i < veces; i++)
{
adapterMarca.InsertMarca(marca);
adapterCoche.InsertCoche(“4444-cxv”, 4, 8);
if (i > 10)
{
// forzamos un error para ver qué pasa
throw new Exception(“prueba de transacción”);
}
}
tran.Commit();
}
catch (Exception ex)
{
tran.Rollback();
}
finally
{
con.Close();
}
}
Aquí­ la pieza que falta es la siguiente, en el diseñador de Datasets, hay que irse a las propiedades de cada uno de los TableAdapter implicados, y establecer la propiedad “ConnectionModifier” a “public”.
Existen otras soluciones a este mismo problema que podéis encontrar descritas en el siguiente artí­culo que explica bastante bien el problema:
https://www.codeproject.com/KB/dotnet/transactionta.aspx
En concreto el autor del artí­culo defiende una solución utilizando Reflection, ya que el otro tipo de solución con la que se suele trabajar para este mismo problema es con el uso de clases parciales.
El problema del uso de las clases parciales es que necesitas generar una clase parcial por cada uno de los TableAdapters, y esto a la larga puede hacer generar mucho código. La solución con Reflection tampoco es la panacea, ya que aunque te evites generar una clase parcial por TableAdapter, aparece el problema de siempre al utilizar Reflection, que nadie te garantiza que tras una actualización del framework la propiedad que has explotado cambie su nombre…
La solución que aporto tiene alguna ventaja, por ejemplo no usa Reflection así­ que nos evitamos problemas de compatibilidades futuras, tampoco es necesario generar una clase parcial por TableAdapter, lo íºnico que tendremos que hacer es en los casos de actuar de forma transaccional (por experiencia el volumen de accesos transaccionales a base de datos no suele llegar ni a la mitad de los accesos de modificación en base de datos) añadir algunas lí­neas más en el código.
Eso sí­, hay una cosa que no me gusta un pelo, que es que tengamos ahí­ en el código la apertura y el cierre de la conexión. Que nos dejemos la apertura lo veo complicado ya que si lo probamos aunque sea una vez nos dará error. El terrible problema lo veo en el cierre de la conexión, ya que es la historia de antaño, como te dejes el finally acabas de reventar tu sistema. Dándole más vueltas, este problemas con una clase que maneje la conexión, que herede de la interfaz IDisposable y que utilicemos mediante un using podrí­amos solventar el problema de olvidarnos cerrar la conexión, pero vamos a seguir teniendo que tragarnos el asignar la conexión y la transacción a todos los adapters que participen.
Saludos.
Miguel.

¿Servicios Web Polimórficos? (Parte 2 – Solución con WCF y Framework 3.5)

Hace ya bastantes artí­culos atrás estuvimos hablando de Servicios Web y Polimorfismo (aquí­). Introdujimos el tema y le dimos alguna vuelta a la necesidad de poder aplicar el concepto de polimorfismo a las llamadas de un servicio web. Es más, incluso lo intentamos utilizando Servicios Web en .NET mediante el Framework 2.0… y… comprobamos que no era posible.
Quedaron abiertas otras soluciones, pero hasta el momento no habí­a podido invertir tiempo en este tema, así­ que ahora que ya tengo algo que mostraros, allá vamos!
Para empezar, como habréis podido observar la solución parte del uso de WCF (Windows Communication Foundation). En concreto para la solución he empleado Visual Studio 2008 y el Framework 3.5 (remarco lo de la versión del Framework, ya que esta misma solución utilizando el WCF y el Framework 3.0 no os va a funcionar, ya que no se hace igual). Estamos de suerte y la solución con el Framework 3.5 la verdad es que es sencillí­sima.
Paso a mostraros fragmentos de código sueltos y luego os adjuntaré el proyecto para que podáis ver y probar vosotros mismos que funciona. Eso sí­, avanzo que el código del proyecto es simplemente para probar el funcionamiento así­ que le faltarán comentarios y demás cosas que intentaré añadir directamente aquí­.
Bien, antes de nada empezar diciendo que voy a intentar seguir la guí­a del primer intento que hicimos de Servicios Web Polimórficos, en la que la idea era conseguir tener un íºnico Servicio Web que nos ofreciera la posibilidad de realizar el mantenimiento de infinitas entidades de datos, en lugar de tener un servicio diferente para cada una de ellas. Para hacerlo necesitábamos que el cliente que consume el servicio recibiera en la definición de su WSDL las clases que implementaban la interfaz IDTO, pero no habí­a manera de que la aplicación de servicios al generar el WSDL lo hiciera de forma automática.
La idea serí­a tener un servicio web que tuviera métodos como los siguientes (para los que no conozcan la teorí­a de los DAO, DTO y Factorí­as, podéis encontrar literatura en la categorí­a de patrones de este mismo blog):
public void Insert(IDTO dto)
{
    Factory.GetDAO(dto).Insert(dto);
}
public void Update(IDTO dto)
{
    Factory.GetDAO(dto).Update(dto);
}
public void Delete(IDTO dto)
{
   Factory.GetDAO(dto).Delete(dto);

Como véis esto serí­a la leche ya que cualquier llamada al servicio serí­a capaz de ejecutar la acción independientemente del DTO que le llegue…
Por aquí­ dejo el código de la factorí­a, que como véis, segíºn el DTO que recibe, retorna el DAO correspondiente.
public class Factory
{
   public static IDAO GetDAO(IDTO dto)
   {
       if (dto is CocheDTO)
       {
          return CocheDAO.GetInstance();
       }
       else if (dto is MarcaDTO)
       {
          return MarcaDAO.GetInstance();
       }
       throw new Exception(“no existe este dto”);
    }
}
Además, como podréis observar, todos los DAO heredan de IDAO, que es quien define los métodos con los que un DAO puede trabajar, y es lo que usa la factorí­a para actuar con independencia.
Pero bueno, vamos al grano y a lo que interesa, que es cómo conseguir que se entere el cliente que recibe el servicio de los DTO que pueden heredar de IDTO. La clave está cuando definimos la clase IDTO.
[DataContract]
[KnownType(typeof(DTO.CocheDTO))]
[KnownType(typeof(DTO.MarcaDTO))]
public class IDTO
{
}
Sobre la clave DataContract, ya hablaremos cuando hagamos la introducción a WCF, en lo que quiero que os fijéis es en las claves KnowType. Aquí­ es donde estamos marcando al servicio que IDTO tiene como tipos conocidos otras clases, que son las que heredan de ella. Por cierto, habréis visto que IDTO es una clase y no un interfaz… por lo visto el atributo KnowType no puede utilizarse con interfaces, pero bueno nos da lo mismo en este caso.
Con todas estas combinaciones que os he presentando, y si probáis el ejemplo donde tenéis más código, veréis que en el cliente que se ha montado (que es una aplicación de escritorio con un botón), podréis leer el siguiente código:
Servicio.MiServicioClient cliente = new Servicio.MiServicioClient();
Servicio.CocheDTO coche = new Servicio.CocheDTO();    
Servicio.MarcaDTO marca = new Servicio.MarcaDTO();     
coche.Codigo =1;
coche.Matricula=”IB-4444-TRT”;
coche.NumeroPuertas=1;
cliente.Insert(coche);
marca.Codigo = 4;
marca.Nombre = “Mercedes”;
marca.Pais = “España”;
cliente.Update(marca);
Bingo! El cliente es capaz de instanciar objetos que no son retornados o pasados por parámetro explí­citamente por un método de un servicio (que era uno de los problemas que tení­amos con el Framework 2.0). “Mágicamente” podemos utilizar los DTO en cliente, rellenarlos y pasárlos a los correspondientes métodos de Insert y Update. Al llegar la petición al servicio, la factorí­a decide el DAO a llamar en tiempo de ejecución y a correr.
Con un íºnico servicio podrí­amos realizar toda la fachada para mantener y consultar infinitas entidades de negocio. ¡Objetivo cumplido!
Os invito a descargar la solución de ejemplo que os adjunto y a lanzarla en modo debug, veréis que si lo seguí­s la ejecución mantiene el flujo que hemos definido sin problemas.
Servicio WCF Polimórfico
Saludos.
Miguel.

Evento Microsoft sobre la Arquitectura Orientada a Servicios

El próximo jueves 8 de mayo se va a producir un evento on-line por parte de Microsoft relacionado con la Arquitectura Orientada a Servicios.
La descripción del evento es la siguiente:
Uno de los temas más polémicos en los íºltimos tiempos en Arquitectura de Software es la orientación a servicios, y cómo esto mejora la agilidad, flexibilidad y el rehíºso de mis soluciones. En esta sesión, nos enfocaremos en la orientación a servicios desde una perspectiva de arquitectura de software, analizaremos cómo un enfoque orientado a servicios difiere de arquitecturas basadas en objetos y componentes, así­ como también la discusión de algunos retos organizacionales que se experimentan al adoptar una arquitectura orientada a servicios”
Muy interesante a priori, el íºnico problema es que para poder verlo en directo tendréis que estar delante del ordenador de 11 a 12 de la noche… 🙂 O esperar más adelante a que pongan a disposición la grabación para ver el ví­deo off-line.
Mas información y suscripción al evento Aquí­
Un saludo.
Miguel.

Desplegando Aplicaciones Web ASP.NET con MSI

Desde hace tiempo querí­a preparar un artí­culo donde se describiera cómo desplegar aplicaciones web ASP.NET mediante archivos MSI. La utilizacion de los MSI resulta en una solución que aumenta la calidad de los despliegues y minimiza la tasa de errores en el proceso.
Es curioso pero ya muchos desarrolladores toman como comíºn y obvio la existencia de aplicaciones que preparan ejecutables para aplicaciones de escritorio, pero no parece que ocurra lo mismo con los despliegues de aplicaciones web, donde no se tiene constancia de que también es posible hacer lo mismo.
En concreto, desde la versión 2005 de Visual Studio se incorpora dicha posibilidad, que brinda toda la potencia que os querí­a presentar aquí­ mismo, pero visto lo visto, tras encontrar el link que abajo os expongo, me parece a mi que no hay mucho más que decir, por lo que me limito a dejároslo para que lo estudieis a fondo. La verdad es que es un artí­culo magní­fico.
Artí­culo
Saludos.
Miguel.