Jornadas 3P

jueves, 6 de diciembre de 2007

En esta oportunidad queremos contarles acerca de nuestra experiencia en lo que denominamos "Jornadas 3P", orientadas a la comunicación e integración de un equipo de trabajo pequeño y al gerenciamiento de los distintos proyectos.

La idea de una Jornada es reunirse en un lugar "neutral", siempre fuera de la oficina, para discutir acerca de diferentes temas que hacen a la empresa y al grupo.


El objetivo principal de estas reuniones es crear un ambiente laboral cómodo y ameno, donde:
  • cada integrante se sienta parte del grupo, una parte importante,
  • cada uno pueda expresar sus ideas libremente y
  • se colabore con el crecimiento tanto de la empresa, como del grupo, y por supuesto, esto tiene una influencia en el crecimiento laboral y personal de cada integrante.


De qué consta específicamente una jornada...

Una jornada es en definitiva una lista de ítems a tratar. Entre estos items se incluyen temas laborales, charlas, recreación o juegos.

Por que incluir juegos… Porque nos parece importante que las jornadas cuenten con espacios para la recreación en conjunto, por lo cual nos gusta incluir juegos y charlas que nos permitan distendernos mientras desayunamos o almorzamos. Esto ayuda a "romper el hielo", así cada uno puede relajarse y sentirse a gusto, sin ninguna presión, y ayuda también a la integración y comunicación del grupo.

Unos días previos a la Jornada se define un cronograma con los ítems a desarrollar, por cada uno se indica: fecha, hora, item y duración, y de ser necesario también se indica un responsable de dirigirlo. Este cronograma se le entrega a cada integrante, con lo cual, al llegar el día de la reunión todos los participantes conocen los temas y el horario de cada uno.

También dentro del cronograma se incluye el horario de cada comida (desayuno, almuerzo, cena).

A Jornadas las podriamos dividir en dos grandes grupos, de acuerdo a la periodicidad con que se realizan:

Jornada trimestral

Se elige algún lugar cerca de la oficina. El mismo tiene que ser cómodo y confortable para que podamos estar reunidos todos juntos o divididos en grupos de 2 o 3 personas, diseminados por el lugar.

En algunos casos elegimos lugares que parecen poco convencionales para una reunión laboral, como por ejemplo el zoológico. Lo importante es elegir el lugar adecuado para crear el ambiente apropiado y así poder tratar los diversos temas con la soltura que necesitamos.

Comienzan a las 9am, con un desayuno y una charla amena, no necesariamente laboral, que permita la participación de todos. Y finalizan con el almuerzo.

Se realizan cada 3 o 4 meses.

Jornada anual

Las jornadas anuales pueden ser de 1 o 2 días completos.

En estas Jornadas se utilizará un pizarrón, se desayunará y almorzará, se realizará algún juego… con lo cual el lugar elegido tiene que tener las condiciones necesarias para que resulte cómodo en el desarrollo de todas las actividades. Una buena ubicación podría ser una quinta.

Las Jornadas de 1 día completo se realizan una vez por año, alrededor de Mayo o Junio.

Comienzan a las 9am y finalizan a las 18hs.

En las jornadas que lleven mas de un día, se elige un lugar "alejado de la civilización", nosotros optamos por la Costa Atlántica (Pinamar o Cariló, como fue este año), y por lo general las realizamos a mediados de Noviembre. También se elige un lugar que nos resulte cómodo tanto para desarrollar las diversas actividades como para hospedarnos.


Que temas se tratan?

Tanto para las Jornadas trimestrales como las anuales, los socios de la empresa son los encargados de decidir cuáles son los principales temas a tratar, y el momento de tratarlos durante la Jornada (ellos realizan el cronograma de items).

Estos temas resultan de inquietudes propias o de los integrantes del equipo, las cuales se exponen al grupo para su posterior evaluación. Por ejemplo, se escriben ideas de temas en un Sharepoint, o se comentan en alguna reunión.

En las Jornadas trimestrales se plantean los posibles temas a tratar en las Jornadas anuales. También se hace una conclusión de cómo resultó lo que se trató en las Jornadas anuales.

En las Jornadas anuales los temas que se tratan estan mas orientados a lo que pasó en el año y lo que esperamos del año próximo.

Cada uno de los temas seleccionado esta dirigido por un integrante del equipo, el cual es responsable del mismo: da una breve introducción, induce al debate entre los integrantes, y en caso de ser un tema a continuar en el tiempo, se lo propone como responsable del seguimiento y cumplimiento de lo acordado.

Los posibles temas a tratar en las Jornadas serian:

  • cómo se siente cada integrante del equipo, con respecto a las tareas que realiza y al entorno de trabajo
  • cuales son sus inquietudes y objetivos, tanto laborales, como personales (si quieren comentar, claro)
  • determinar un plan de trabajo para el año en curso y el siguiente (Jornadas anuales)
  • para los proyectos finalizados, se analiza qué nos dejó: errores y aciertos, para aplicar el aprendizaje en el futuro
  • cada integrante expresa su opinión acerca de la empresa: lo que es, lo que espera que sea y el lugar que espera ocupar (Jornadas anuales)

Pinamar - Cariló 2007

Nuestra mas reciente Jornada fue en Noviembre, la cual duró 2 días. El lugar elegido fue un complejo de cabañas sito en Cariló (se encuentra en la Costa Atlántica).

Se trataron diferentes temas, entre los principales podemos destacar:

  • como ve cada uno a Tercer Planeta: cual es la imagen que tenemos y que queremos lograr, y que hay que hacer para alcanzarlo
  • expectativas y/o proyectos personales
  • expectativas con respecto a la Jornada
  • qué anduvo bien y qué anduvo mal en el año
  • charlas individuales de los socios con cada integrante
  • objetivos 2008
  • comunicación interna (¿Nos comunicamos bien? ¿Qué podemos hacer para mejorar? ¿Hay quejas?)
  • capacitaciones

Conclusiones

El objetivo principal de realizar una Jornada es facilitar la comunicación e integración del grupo. Mediante charlas, debates, exposición de ideas e inquietudes o juegos se logra poder conocer un poco mas a la persona con la que trabajamos y convivimos todos los días, y logramos poder hablar libremente.

Otro objetivo importante es poder definir los lineamientos de la empresa, tener la capacidad de ver los aciertos y errores, para potenciar y corregir lo necesario y establecer un plan de trabajo tanto de la empresa como de los integrantes.

Cuando los objetivos son claros y conocidos, es sencillo alcanzarlos...

Cuando el grupo esta integrado y motivado, ¡el trabajo resulta menos denso y el ambiente laboral resulta agradable!

Por lo cual les recomendamos ampliamente la práctica de una Jornada, de acuerdo a las necesidades y estructura organizacional.

¡Animense! ¡No es imposible!

Leer más...

Uso de Team Foundation Server Source Control en VB6: proveedor MSSCCI para TFS

Para quienes hemos adoptado Visual Studio 2005 Team Foundation Server como administrador de código fuente, una necesidad frecuente es la de integrar en el mismo repositorio el trabajo desde otras herramientas anteriores a VS 2005, por ejemplo Visual Basic 6.0, Visual FoxPro 9, Visual Studio .NET 2003, etc.

Para estos casos Microsoft ha liberado en diciembre 2006 el proveedor MSSCCI correspondiente a Team Foundation Server, haciendo posible la integracion de código fuente con TFS en cualquier herramienta compatible con el estandard MSSCCI. El software puede descargarse aquí: http://www.microsoft.com/downloads/details.aspx?FamilyId=87E1FFBD-A484-4C3A-8776-D560AB1E6198&displaylang=en

Debe tenerse en cuenta que este proveedor MSSCCI es sólo el conector entre las herramientas cliente y el TFS, y no incluye un "explorador" del arbol de código similar al Team Explorer (TFS) o el Source Safe Explorer (VSS). Para esas tareas de exploración debe utilizarse (y de hecho es un prerequisito de la instalación) el Team Explorer, que es una extensión a la IDE de Visual Studio 2005

Lo que el conector sí realiza, en herramientas que tienen integración con un Source Control Provider, es permitir que dentro de la IDE respectiva (p.ej. en VB6, o VFP 9, VS.NET 2003) se acceda en forma transparente al repositorio de código montado en Team Foundation
Server.

Veamos por ejemplo los pasos para integrar en un proyecto VB6 el control de código de TFS

  1. Instalar Team Explorer, incluido en el CD de instalación de Team Foundation Server
  2. Instalar el proveedor MSSCCI descargado del link mencionado previamente
  3. Verificar que Visual Basic tenga aplicado el ultimo Service Pack (SP6, actualmente)
  4. Cerrar y reiniciar la IDE de VB si está abierta.
  5. Desde la IDE de VB, en la opción Add-ins / Add-in manager... del menú, seleccionar activar la opcion "Source Code Control", (asignarle Startup + Loaded)
Una vez cargado el add-in, pueden realizarse las operaciones normales de integracion con source control utilizando el menú contextual sobre el explorador de proyectos (check-in, check-out, etc) y las opciones de menu (Toosl / Team Foundation).
Asimismo, al grabar un proyecto no integrado a Source Control aparecerá el diálogo consultando si se desea agregarlo.

Para otras operaciones más específicas sobre el repositorio de código (ej. modificación de workspaces, operaciones de "branch" y "merge", etc) se utiliza la interfaz visual del Team Explorer.

Notas:
Leer más...

LINQ: el futuro se nos vino encima

miércoles, 21 de noviembre de 2007

... y cuando quisimos darnos cuenta, ya estaba acá

Anteayer (19/11/07) Microsoft hizo públicos

Hay tantas novedades en esta version del producto....

En nuestra opinion, el mayor impacto (y el mayor trabajo de difusión, discusión y esclarecimiento) gira en torno a LINQ y las extensiones a los lenguajes C# y VB que lo soportan.

Se abre un mundo de posibilidades que hay que explorar, entender, elegir...

Vuelva a este blog para más discusiones sobre el tema, en breve!

Jose.

Leer más...

Las buenas prácticas de desarrollo siempre pagan

lunes, 12 de noviembre de 2007

En estos días estuvimos evaluando un conjunto de aplicaciones desarrolladas durante los últimos siete años por una importante cadena de supermercados en Argentina, en el lenguaje Visual FoxPro.

Cuando en 2000 se inició el proyecto de reemplazo de su sistema completo de gestión comercial y de inventarios, nos convocaron para participar en la definición de la arquitectura y la construcción de un framework de clases que sirviera de base para el crecimiento futuro de la aplicación.

Siete años y más de cien mil horas de horas de programación despues, nos tocó evaluar la factibilidad y costo de la conversión a .NET (C#) de toda la lógica de negocios, desarrollada en VFP por un equipo de programadores que se sucedieron en el tiempo agregando funcionalidad y nuevos módulos

Para la evaluación desarrollamos un parser en C#, que realiza un análisis “drill down” del código Visual FoxPro analizando las clases y métodos y verifica cuánto del código es mapeable a expresiones simples con invocaciones a métodos básicos (y por lo tanto, es convertible en forma automática con una herramienta a desarrollar).

En este proceso de evaluación constatamos algunas suposiciones iniciales, y nos llevamos algunas sorpresas:

Arquitectura. Tal como se esperaba, lo que por diseño se concibió para ser interoperable participa a la perfección en el proceso de evolución de la arquitectura:
  • Los componentes de negocios, todos implementados como componentes COM que intercambian XML y acceden a datos en SQL Server, pueden ser “mapeados” exactamente a los nuevos componentes en .NET implementados como servicios.
  • En la capa de presentación, el hecho de haber implementado desde el principio un “dispatcher” que centraliza las invocaciones a la capa de negocios permite introducir fácilmente un conmutador de las llamadas para encaminarlas a los componentes COM originales o bien a los nuevos servicios .NET (Strategy Pattern, GOF).
  • Esto permitirá que la conversión de la lógica de negocios y el reemplazo de componentes se realice en forma gradual, y de hecho permitiría escenarios de coexistencia de las tecnologías en forma permanente, si esa fuera la estrategia deseada.
Prácticas de desarrollo. Con cierta sorpresa, dada la cantidad de programadores que se alternaron durante el proceso de evolucion de las aplicaciones, constatamos un muy alto nivel de calidad y de homogeneidad en las prácticas de desarrollo:

  • De los más de 12000 métodos presentes en la capa de negocios, más de 7000 tienen de 1 a 10 líneas de código, y otros 2000 entre 11 y 20 líneas; con un altísimo grado de reuso de los métodos y clases base para la funcionalidad de uso frecuente.
  • El análisis sintáctico del código permite estimar en más de 8500 los métodos directamente convertibles en forma automática, por consistir en invocaciones a métodos del framework propio con expresiones o comparaciones simples (If …. Then, etc), con otros 2000 métodos que también pueden convertirse en forma automática pero requieren algun grado de revision manual.
En conclusión, y sin minimizar la magnitud que requerirá una tarea de migración tecnológica tan importante (por la evolución cualitativa que representa .NET), constatamos con satisfacción que el costo inicial de desarrollar una arquitectura distribuida, interoperable, y de establecer un marco y prácticas de desarrollo precisas, tiene un triple efecto de devolución:

  • En la calidad del sistema, que permitió el crecimiento y evolución de la cadena durante estos años, y su mantenibilidad aún cuando los equipos vayan renovandose.
  • En la posibilidad concreta, y ya puesta en práctica, de integrar los componentes originales con otros desarrollados en tecnologías radicalmente nuevas, sin necesariamente encarar una reconversión completa.
  • En las enormes ventajas, en caso de encarar una reconversión, de partir con mucho terreno ganado y una proporcion muy mayoritaria de código que puede convertirse automáticamente.
Considere estos factores a la hora de encarar su próximo proyecto: “quick and dirty” (rápido y sucio) no siempre siempre resulta rápido; pero casi con seguridad va a resultar sucio y finalmente caro.
Leer más...

Seguridad integrada con SQL Server en un sitio web ASP.NET

miércoles, 20 de junio de 2007

Una consulta muy frecuente que recibimos es “como configurar un sitio web para acceder a SQL Server mediante seguridad integrada”, bajo la situación más habitual (y recomendada) que es aquella en la cual los usuarios que acceden al sitio no utilizan seguridad integrada de Windows o, aún en caso de hacerlo, no tienen asignados permisos individuales de acceso a la base de datos de la aplicación.

La implementación de este escenario, en la plataforma actual de servidores Web de Windows (Windows Server 2003), consta de los siguientes pasos:

1. Definir un usuario del dominio para ejecutar la aplicación web y acceder al SQL Server

Crear una cuenta de usuario en Active Directory, designada para ejecutar las aplicaciones web y acceder al SQL Server. Es recomendable que esta cuenta no sea administrador del dominio, ni del equipo en que ejecuta el website o el SQL Server.

2. Asignar permisos a ese usuario en Microsoft SQL Server

Mediante el SQL Server Management Studio (SQL Server 2005) o el SQL Server Enterprise Manager (SQL Server 2000) definir, dentro de la seccion Security, una cuenta (login) de seguridad integrada correspondiente a la cuenta designada del dominio; asignarle permisos sobre las bases que corresponda, solamente con los privilegios que requiera para ejeutarse.

3. Preparar la cuenta para ejecutar aplicaciones ASP.NET

Este es un paso comunmente omitido, que resulta en la imposibildad de ejecutar correctamente el sitio.
En el equipo en que se ejecuta el sitio Web (Internet Information Server) configurar lo siguiente:

  1. Asignar a la cuenta designada permisos de control total sobre la carpeta temporaria de Windows (habitualmente C:\Windows\Temp).
  2. Desde la línea de comandos posicionarse en la carpeta correspondiente al framework .NET en uso (por ejemplo C:\Windows\Microsoft.NET\Framework\ v2.0.50727) y allí ejecutar el siguiente comando:
    aspnet_regiis –ga {dominio\cuenta}
    reemplazando {dominio\cuenta} por la cuenta designada en el paso 1

4. Asignar la cuenta designada como identidad del proceso ASP.NET

En Windows Server 2003, eso se realiza en la consola de Administración de Servicios Internet (IIS) asignando la identidad del Application Pool que se utiliza para ejecutar la aplicación Web.
IMPORTANTE: si la aplicación está configurada para ejecutar en el “Default App Pool”, u otro compartido con múltiples aplicaciones, puede ser conveniente definir un application pool separado para los sitios que deban ejecutarse bajo esta cuenta de usuario, y asignar los sitios al App Pool creado.

5. En la aplicación ASP.NET, asegurarse que no esté activa la “impersonación”

Si se utiliza Authentication mode=”Windows”, asegurarse que en el archivo Web.config no exista un elemento <identity> o, si existe, asegurarse de que tenga asignado el atributo impersonate=”false”.
De ese modo, el proceso se ejecutará con la cuenta designada.
NOTA: sin necesidad de impersonar, desde el código de la aplicación Web puede conocerse el nombre de la cuenta autenticada mediante la propiedad User.Identity



Con estos pasos, se lograrán los objetivos buscados:

  • Evitar incluir nombres de usuario y password en la configuración de la aplicación (o en cualquier otro componente de la misma)
  • Ejecutar el sitio web con una cuenta que no tenga más privilegios de los requeridos
  • Evitar otorgar permisos sobre la base de datos a los usuarios del sitio.
Leer más...

SQL Server 2005 sobre Windows Vista

martes, 12 de junio de 2007

Dos recomendaciones muy importantes para utilizar SQL Server 2005 sobre el sistema operativo Windows Vista

1) En todos los casos (se trate de las herramientas cliente, o el motor de base de datos) instalar el Service Pack 2 de SQL Server 2005
http://www.microsoft.com/downloads/browse.aspx?displaylang=es&productID=9F07F9CC-C308-4EBF-A4E9-2B8530AB1EA8

2) Adicionalmente, si se ha instalado el server (motor de base de datos) sobre uno de estos sistemas operativos, tener en cuenta que cambia el manejo por defecto de la seguridad:

Al instalar un SQL 2005, automáticamente se agrega un login para el grupo BUILTIN\Administrators, con permisos de sysadmin.
Sin embargo, el manejo de seguridad de Windows Vista hace que un usuario, aunque sea administrador del equipo, no ejecute las aplicaciones como tal salvo cuando lo hace con "privilegios elevados" (Run as administrator)

Por lo tanto hay dos opciones para que un usuario administrador del equipo tenga privilegios completos de administracion del SQL Server 2005 en ese equipo:

a) [No recomendado] Ejecutar el SQL Server Management Studio mediante la opción "Run as Administrator"

b) [Recomendado] Empleando el "SQL Server Surface Area Configuration", agregar la cuenta del usuario para que actúe como administrador (opcion Add New Administrator)

Para más información sobre las buenas prácticas de administración y operación SQL Server 2005, puede descargarse este documento de Microsoft (en inglés):

SQL Server 2005 Security Best Practices - Operational and Administrative Tasks
Leer más...

Exception Handling y Logging con Enterprise Library 3.0

lunes, 11 de junio de 2007

En este artículo voy a mostrar como agregar un manejo simple de excepciones, y luego logging de éstas y otros eventos usando Enterprise Library 3.0, sin profundizar en todas las posibilidades que éstas librerías ofrecen.

Usaremos en este ejemplo los siguientes bloques de Enterprise Library 3.0:

  • Exception Handling Application Block
  • Logging Application Block (que registrará Excepciones recibidas por el bloque anterior, y otros mensajes de bitácora)
  • Data Application Block (para permitir al bloque anterior, Logging sobre una base de datos SQL)

(Es condición previa en el ejemplo siguiente, agregar referencias en nuestro proyecto a los assemblies correspondientes)

De la aplicación de ejemplo realizada en C#, nos interesa el siguiente bloque de código:


Vamos a trabajar sobre este método, que resulta crítico para nuestro sistema, por lo cual queremos una bitácora de su ejecución y resultado.



Exception Handling Application Block


Este bloque nos permite delegar el manejo de una excepción a una policy definida en archivos de configuración. En particular nos permitirá encapsular, reemplazar, absorber excepciones, o enviar éstas al Logging Application Block para registrarlas en una bitácora.

Para esto basta con modificar nuestro código de la siguiente manera:



Interceptamos cualquier tipo de Exception, y la manejamos con el método estático:

ExceptionPolicy.HandleException()

Éste recibe la excepción a ser manejada, el nombre de la policy a aplicar (a continuación vamos a definir esta política), y opcionalmente un parámetro out en el que se devuelve la excepción que reemplaza a la original (esto sucede cuando la policy utilizada decide que la excepción debe ser reemplazada o contenida dentro de una nueva), si la excepción no debe ser reemplaza este parámetro toma el valor null.

Este método devuelve true si la excepción (o la excepción que la reemplaza) debe ser relanzada.


Ahora sólo resta definir nuestra "TareasPolicy", para eso alcanza con editar el archivo de configuración (app.config, web.config, *.config) con la herramienta gráfica que incluye Enterprise Library (Enterprise Library Configuration Tool), con la cual resulta trivial lo siguiente:

  1. Agregar un bloque de configuración para Exception Handling, y dentro de éste crear una nueva policy con el nombre "TareasPolicy".
  2. Definir en esta policy para el tipo de excepción Exception (es decir para todas), un Logging Handler, y definimos para este Handler, que las excepciones produzcan entradas de Log de nivel "Error" (lógicamente), y con la categoría "Errores", vamos a ver que implica esto a continuación.

Dentro de una policy podemos definir también los siguientes Exception Handlers, que pueden utilizarse según el tipo de Exception lanzada:

Wrap Handler: Envuelve la excepción lanzada dentro de una nueva.
Replace Handler: Reemplaza la excepción con una nueva.
Logging Handler: Transfiere la excepción al Logging Application Block para poder registrarla en una bitácora.
Custom Handler: Permite manejar una excepción utilizando una clase definida en nuestra aplicación.
Fault Contract Exception Handler: Facilita el manejo de excepciones en aplicaciones SOA.



Logging and Instrumentation Application Block


Necesitamos ahora indicar como serán tratadas en este bloque las excepciones recibidas, pero antes es preciso definir las entidades más importantes en este bloque:

Trace Listener: Manejan los eventos registrándolos o emitiéndolos en distintos medios, son los siguientes:
  • Formatted EventLog: registra los eventos en el EventLog del sistema.
  • Flat File: simplemente almacena los eventos en un archivo de texto plano.
  • Rolling Flat File: utiliza un archivo de texto, que al alcanzar una antigüedad o támaño máximo se cierra y comienza uno nuevo.
  • Xml: en este caso el log generado es un documento xml, asimismo las entradas pueden contener un campo xml.
  • Email: envía notificaciones de eventos a traves de un servidor SMTP.
  • Msmq: utiliza Microsoft Message Query como destino de los eventos.
  • WMI: los eventos se manejan con Windows Management Instrumentation.
  • Database: Cuando recibe un evento, invoca un stored procedure con sus datos como parámetro. (Requiere el Data Access Block, para definir la base de datos a utilizar).
  • Custom: Si los anteriores no son suficientes, puede manejarse los eventos mediente una clase definida nuestra aplicación. Esto nos permitiría por ejemplo, mostrar un MessageBox, enviar el error con un POST HTTP, etc.
Formatter: Se encarga de serializar eventos, para facilitar su almacenamiento, son los siguientes:

  • Text Formatter
  • Binary Formatter
  • Xml Formatter
  • Custom Formatter
Event Sources: Representan fuentes de eventos, se les puede asociar uno o más Trace Listeners.
Pueden definirse segun categoría de los eventos, y están predifinidas adicionalmente las siguientes sources especiales:

  • All Events: Como su nombre lo indica, recibe todos los eventos de la aplicación.
  • Unprocessed category: Eventos de categorías no procesadas.
  • Logging Errors & Warnings: Recibe errores y advertencias producidos al registrar otros eventos (por ejemplo, caída del servidor del SQL, al intentar almacenar un evento en éste), permite una especie de "manotazo de ahogado", lo que hace apropiado asociar a esta fuente el Event Handler más "infalible", por ejemplo, Formatted EventLog.
Filters: Permiten filtrar eventos, según categoría, prioridad, o mediante clases personalizadas.


Ahora utilizamos una vez más la herramienta de edición de archivos de configuración para lo siguiente:

  1. Definir el bloque de configuración para el Logging Application Block.
  2. Definir el Category Source "Errores" como fue definido en el Exception Handling Block, este recibirá las Exceptions interceptadas por éste, y asociaremos a este un Database Handler, para crear nuestra bitácora en una base de datos.
  3. Crearemos (si no existe aún) la configuración para el Data Access Application Block, donde definiremos el connection string.
  4. Referenciar esta base de datos en nuestro Database Trace Listener, e indicar en éste el nombre del stored procedure que debe invocarse para agregar una entrada al log, y el stored procedure que se invoca inmediatemente después para indicar la categoría de ese evento (es por esto que el primer stored procedure, debe devolver el id de la entrada creada).
  5. Dado que nuestra conexión con la base de datos puede fallar (y queremos saber cuando!), agregamos un Formatted Event Log Trace Listener, y asociamos este al "Logging Errors & Warning" Special Source, para registrar en el EventLog los errores que ocurran al intentar usar la base de datos.

Por último aprovecharemos el Logging Application Block, para registrar también información adicional sobre la ejecución de nuestra tarea, para eso asociaremos nuestro Database Trace Listener al Special Source "All Events" (es posible definir un Trace Listener, o una categoría especial de eventos para este caso)

Ahora podemos modificar nuestro código C# de esta manera:


El método estático Logger.Write(), puede recibir también varios parametros adicionales como categoría, prioridad, severidad, etc.



Conclusiones

  • Las políticas de manejo de errores y logging, son totalmente independientes del código fuente: pueden ser establecidas de forma gráfica, en archivos de configuración, sin necesidad de recompilar la aplicación. Es decir, la modificación de estas políticas pueden ser delegada a un usuario administrador.
  • Por la misma razón que el punto anterior, al agregar estos bloques a una aplicación existente, el impacto sobre el código fuente es mínimo.
  • El manejo de Excepciones y Eventos de Log, es extensible definiendo "custom handlers", clases personalizadas que son invocadas para estas tareas.



Links


UPDATE 2009-06-12

Fe de erratas!, Como comenta Ariel (ver comentario en esta entrada), la forma correcta de relanzar una excepción es mediante throw; (de forma de mantener el stack trace), asi que en todos los bloques de codigo donde dice:

throw outEx ?? ex;

debería leerse:

if(outEx!=null)
throw outEx;
else
throw;
Leer más...

SQL Compact Edition

viernes, 18 de mayo de 2007

Presentación

SQL Compact Edition es un nuevo integrante de la familia SQL de Microsoft, y se trata de un motor SQL muy liviano y portable, pensado para utilizar pequeñas bases de datos en forma local.
Esta nuevo producto es la evolución de SQL Mobile Edition, el cual nos permitía tener un "mini" motor SQL en dispositivos portátiles (PocketPCs, Smart Phones), ahora extendido al resto de la sistemas operativos Windows (Tablet PCs y computadoras de escritorio).



Arquitectura

SQLCe, a diferencia de sus hermanos mayores, no se trata de un servicio de datos (tipicamente accesible de forma permanente, esperando consultas de aplicaciones cliente, locales o remotas), sino que se trata de una libreria (dll) que es refernciada por la aplicación cliente, es un motor "embebido" en la aplicación, optimizado para dispositivos de escritorio o portátiles.



Características Principales

  • SQLCe acepta sintaxis Transact-SQL, lo que lo vuelve facilmente escalable a sus hermanos mayores (SQL Express Edition, Standard Edition, etc). Aún así a la hora de portar código desde/hacia otro SQL Server es necesario tener en cuenta algunos puntos, por ejemplo: los tipos de datos en SQLCe, son un subconjunto de los disponibles para SQL Express Edition.
  • No pueden utilizarse Stored Procedures, esta limitación es clave a la hora de pensar en escalabilidad. Puede ser el punto que nos lleve a inclinarnos por SQL Express Edition. Más adelante, en una comparación entre SQLCe y SQL EE voy a resumir algunas razones por las que podría prescindirse de Stored Procedures.
  • Una base de datos SQLCe se almacena en un único archivo, lo que facilita la transferencia de bases de datos individuales.
  • SQLCe es un conjunto de librerías de alrededor de 2Mb, que pueden ser distribuídas con nuestra aplicación sin necesidad de registrar componentes, ni servicios, por lo tanto, no se necesitan privilegios de administrador durante la instalación, y los recursos de memoria y espacio en disco son mínimos.
  • Dado el tipo de dispositivos en los que SQLCe pretende funcionar (desde notebooks, pc's de escritorio a pocket pcs y smartphones), cuenta con características de seguridad, y protección contra errores (robo, perdida de energía) que son exclusivos para estas plataformas.
  • Herramientas para la sincronización de datos con SQL Server 2005

Veamos algunos puntos a tener en cuenta al decidir entre SQL Compact Edition y otras bases de datos locales.

SQL Compact Edition vs. XML o Archivos de Texto

  • Consultas, transacciones y manipulación de los datos
  • Encriptación nativa

SQL Compact Edition vs. Access o FoxPro

  • Integración con Visual Studio
  • Compatibilidad con el resto de la familia SQL Server

SQL Compact Edition vs. SQL Express Edition


SQL Compact Edition y SQL Express Edition se presentan como las dos opciones, ambas gratuitas, a la hora de implementar bases de datos locales en PC's de escritorio (Windows XP/Vista o Tablet PC), en cambio la opción es clara para dispostitivos móviles (SQLCe), y para bases de datos centrales, multiusuario (SQL Express).

  • Stored Procedures

Para los que estén acostumbrados a trabajar con bases de datos centrales, de gran escala, con múltiples usuarios accediendo concurrentemente con diversos privilegios, resulta inmediato basar la capa de datos en Stored Procedures, las históricas razones de esto son 3, voy a resumir porque estas razones podrían no tener tanto peso en un escenario muy distinto, como es una base de datos embebida, local y monousuario (escenario al que apunta SQL Ce).

  1. Rendimiento: Los stored procedures permiten ejecutar código de acceso a datos, optimizado para este uso. Sin embargo teniendo un solo usuario, sobre una base de datos local, implica que las consultas no llegarán con mayor concurrencia que los clicks de un usuario, por lo tanto (en lo que a performance se refiere) resulta aceptable codificar esta lógica procedural en la capa de datos de la aplicación.
  2. Abstracción: Acceder a los datos únicamente con stored procedures, es una forma de construir una capa de abstracción sobre éstos, sin embargo tanto el motor de SQLCe como las bases de datos pueden ser distribuídas y versionadas junto con la aplicación, y el beneficio de mantener esa abstracción ya no resulta tan evidente.
  3. Seguridad: Una vez más, los stored procedures permiten restringir el acceso a los datos, permitiendo únicamente ciertas operaciones sobre éstos, sin embargo la base de datos es distribuída con la aplicación y el usuario es único, en este escenario tienen más sentido otras medidas de seguridad, como encriptar la base de datos, e incluir en ésta únicamente el subconjunto de datos que el usuario local necesita.
  4. Dicho esto, por supuesto hay que evaluar la escalibilidad de nuestra aplicación, para evitar a toda costa verse en un futuro en la situación de traducir procedimientos C#/Vb.NET, a Transact-SQL.
  • Recursos, SQL Ce requiere de solo 2Mb en disco y un uso de memoria y procesador muy inferiores a SQL Express Edition, que al instalarse ocupa alrededor de 200Mb en disco, y al ser un servicio, se encuentra constantemente esperando ser invocado por una aplicación cliente (a pesar de estar preparado para "adormecerse" en períodos de inactividad)
  • Instalación, SQL Ce, puede distribuirse con nuestra aplicación, de manera que no requiera privilegios de administrador para instalarse y poder controlar su versionado. Alternativamente puede (como SQL Express) instalarse mediante un MSI, y recibir actualizaciones de Windows Update.
  • Almacenamiento, Ambos motores esta limitados a bases de datos de 4Gb, sin embargo las bases de datos de SQLCe estan contenidas en archivos individuales, "code-free" (sin código ejecutable, no sucede lo mismo con bases de datos de SQL Express), que pueden ser encriptados y protegidos con contraseña. Por lo tanto estos archivos pueden ser facilmente enviados, backupeados y asociados a una aplicación mediante una extensión de archivo particular.




Sql Ce con Enterprise Library 3.0

Una de las novedades en Enterprise Library 3.0 es la incorporación de clases para el manejo de SQL Compact Edition, bajo el nuevo namespace System.Data.SqlServerCe.

Una curiosidad es que el manejo de conexiones abiertas es distinto a los demás providers en Enterprise Library, por lo cual es aconsejable (para mantener la performance) utilizar transacciones para mantener una conexion abierta en operaciones en lote. Este comportamiento es explicado aqui:

http://www.codeplex.com/entlib/WorkItem/View.aspx?WorkItemId=9005

(fue reportado como bug, aunque la respuesta aclara que fue una decisión de diseño)

Links

http://www.microsoft.com/sql/editions/compact/default.mspx

http://www.microsoft.com/sql/editions/compact/sscecomparison.mspx

http://www.codeplex.com/entlib/WorkItem/View.aspx?WorkItemId=9005

Leer más...

Cryptography Application Block

Introducción

Este es un bloque de aplicación integrado en las versiones de Enterprise Library 2.0 y 3.0, basado en la criptografía, que intenta facilitarla y acercarla a los desarrolladores y sus aplicaciones, pudiendo utilizarlo para encriptar información, crear datos compactados y compararlos para verificar que la información no ah sido alterada.

Dentro de las principales características encontramos

  • Reduce los requerimientos para escribir código normalizado proveyendo implementaciones para solucionar problemas comunes de criptografía.
  • Ayuda a mantener prácticas consistentes de criptografía en la aplicación y la empresa.
  • Facilita la curva de aprendizaje de los desarrolladores usando un modelo de arquitectura consistente a través de varias áreas de funcionalidad que son provistas.
  • Provee implementaciones que pueden ser utilizadas para resolver los problemas básicos.
  • Es esténcil y soporta implementaciones adicionales de criptografía.


  • Escenarios comunes

    Los desarrolladores frecuentemente escriben aplicaciones que requieren encriptación y compactación de datos, para cumplir los requerimientos de seguridad de la organización. Tanto los datos que son creados y mantenidos por las aplicaciones como la información de configuración necesitan ser resguardadas. Adicionalmente las contraseñas que son usadas para acceder a la funcionalidad o datos de la aplicación requieren compactación. También favorece la abstracción del código de la aplicación respecto al de los proveedores de criptografía, permitiendo el cambio en la encriptación sin necesidad de modificaciones en el código del resto de la aplicación.
    Este bloque solo soporta algoritmos simétricos, que utilizan una misma llave para ambos procesos, pero no así los asimétricos, para los cuales el método de encriptación y desencriptación difieren en el código.

    Objetivos

  • Proveer una interfase simple e intuitiva para las funcionalidades más comúnmente requerida.
  • Encapsular la lógica de encriptación.
  • Lograr un modelo consistente y estandarizado para las tareas comunes relacionadas con la criptografía.
  • Asegurar un bloque de aplicación extensible.
  • Minimizar el impacto de las funciones criptográficas al resto de la aplicación.
  • Proveer un modelo basado en una “llave” que puede ser modificada por el usuario, para personalizar la encriptación.


  • Estructura y posibilidades

    El bloque separa las implementaciones de la encriptación y el resto de la aplicación permitiéndonos modificar uno sin alterar en nada el funcionamiento del otro. Dentro del mismo podemos encontrar con tres diferentes ámbitos.
  • La clase “Cryptographer” es una interfase que media entre el código de la aplicación y las funciones del “Cryptography Application Block”. El código del cliente llama a métodos estáticos de esta clase para crear compactaciones de información, compararlas, encriptar y desencriptar datos. Cada método estático llama a una clase de generación y pasa el código de configuración al constructor de la clase, con el mismo la clase determina que tipo de proveedor crear.
  • La clase “DpapiCryptographer” utiliza DPAPI (Data Protection API) para encriptar y desencriptar datos. DPAPI utiliza las credenciales de logueo para encriptar los datos, las mismas pueden ser de un usuario en una máquina o dominio, o de una computadora dentro de una red. En el caso de utilizar las credenciales de logueo de un usuario en una máquina, estas permiten que cualquier aplicación que el mismo usuario ejecute, pueda desencriptar toda información resguardada bajo la misma llave. Para no permitir esto se puede utilizar una clave o “entropy”. Hay métodos sobrecargados en la clase que permiten encriptar y desencriptar utilizado esta clave.
    Es importante remarcar que la necesidad de resguardar la seguridad de esta clave es tan necesaria como la encriptación de la información sensible.
  • La clase “SymmetricCryptographer” encapsula la implementación de la clase base abstracta “SymmetricAlgorithm”, la cual se encuentra dentro de “System.Security.Cryptography” en el .NET Framework. Esto significa que la clase en cuestión nos permite utilizar cualquier algoritmo simétrico de encriptación como por ejemplo el “Rijndael”. El bloque de aplicación utiliza DPAPI para encriptar y desencriptar la clave del algoritmo simétrico.


  • Conclusiones

    Este bloque de aplicación no intenta solucionar todos los casos en los cuales el resguardo de información y por ende la encriptación de los datos es necesaria, sino facilitar a los programadores novatos los primeros pasos, sin perder de vista que para determinadas aplicaciones, este bloque es lo suficientemente completo como para cumplir con todos los requisitos de seguridad de la misma. Con esto queremos concluir en que si bien el bloque es muy útil en muchos tipos de aplicaciones no hay que forzar la utilización del mismo en cualquier desarrollo, sino estudiar previamente si cumple con los requisitos que tenemos en ese momento.
    Leer más...

    Accediendo a la configuración

    lunes, 7 de mayo de 2007

    La clase ConfigurationManager (incluida a partir de la versión .Net 2.0) perteneciente al NameSpace System.Configuration, nos permite acceder a los archivos de configuración de nuestra aplicación.

    Esta incluye miembros que permiten llevar a cabo las siguientes tareas:


    • Leer una sección de un archivo de configuración.

    • Leer y escribir totalmente archivos de configuración.

    • Compatibilizar tareas de configuración.


    Un motivo importante para utilizarla, es que nos independiza del tipo de aplicación final que estemos construyendo (Aplicación de escritorio, Sitio Web, Web Service, etc).

    Para poner un ejemplo práctico, en una aplicación en 3 capas típica, es normal querer obtener el String de Conexión en la capa de acceso a datos, para poder conectarnos con nuestra base de datos.

    Supongamos que este String de conexión lo tenemos almacenado en el archivo de configuración de nuestra aplicación (app.config para una aplicación WinForms, web.config en una aplicación ASP.NET, etc) .

    Una de las maneras de acceder a esta información sería escribir el siguiente código dentro de nuestra capa de acceso a datos, sin importar que tipo de aplicación final la este consumiendo:


    string conString = System.Configuration.ConfigurationManager.
    ConnectionStrings["Conexion"].ConnectionString;

    Para este ejemplo en particular deberíamos incluir en nuestro archivo de configuración, estas lineas dentro del tag Configuration:

    <connectionstrings>
    <add name="Conexion" connectionstring="Data Source=localhost;
    Initial Catalog=NombreBD; Integrated Security=True">
    </connectionstrings>

    Utilizar las clases que nos provee .Net FrameWork es una buena práctica, principalmente para no perder tiempo en escribir código, que ya tengamos disponible para nosotros.

    Para poder acceder a esta clase debemos referenciar al ensamblado: System.Configuration (en system.configuration.dll).

    Este es uno de los usos que le podemos dar a esta clase, quizás el más utilizado, para más información dejo un link.

    http://msdn2.microsoft.com/es-es/library/system.configuration.configurationmanager(VS.80).aspx

    Leer más...

    Lean Product Development

    viernes, 4 de mayo de 2007

    Lean es una metodologia genérica para mejorar la calidad y productividad. Es usada exitosamente en industrias de manufacturación o logística.

    Lean Product Development es una variación de la metodologia Lean, toma los principios Lean para aplicarlos en el diseño y producción de software. Se basa en la identificación y eliminación de cualquier fuente que genere "desperdicios", para que los objectivos globales se cumplan exitosamente, estimulando la productividad. El uso de esta metodologia puede ser el paso previo al uso de metodologías de las llamadas Agiles.

    Los principios Lean, aplicados al desarrollo de software, son:
    • Eliminar los desperdicios
      Es el principio fundamental y del cual dependen el resto de los principios.

      Significa invertir el tiempo solo en aquello que agregue valor real.
      Hay que entender cual es el valor real y qué actividades y recursos son necesarios para crearlo. A menudo, el trabajo de determinar qué es y qué agrega valor se hace en los niveles altos de la jerarquía.

      Los principales tipos son:
      Funcionalidad que se desarrolla y no se utiliza en producción. Esto genera código extra, el cual tuvo que seguirse, compilarse y testearse, el mismo incrementa la complejidad y es un posible punto de fallo.
      La documentación, consume recursos, demoras, se pierde y se vuelve obsoleta. Si se utiliza, que sea solo la necesaria.
      Asignar una misma persona a múltiples proyectos. Cada vez que el desarrollador de software tiene que cambiar entre tareas, pierde un tiempo significativo para recordar de que se trataba el proyecto. Pertenecer a diferentes equipos de trabajo causa más interrupciones que beneficios.
      Las Esperas, uno de los grandes desperdicios, en cuanto a tiempo, es esperar a que sucedan cosas: se espera al comienzo del proyecto, en la definición de requerimientos, en el armado de la excesiva documentación, en la codificación, en revisión y aprobación, en testeo, etc.
      Puesta en marcha, cuando un desarrollador tiene una pregunta, ¿cuanto cuesta encontrar la respuesta? Los requerimientos van a los analistas, de los analistas a los diseñadores, de aquí a los desarrolladores y luego al testeo… en cada pasaje es probable que se pierda algo, ya que un porcentaje de conocimiento tácito queda con el creador del documento y no se transmite.
      Errores en el Software, el porcentaje de desperdicio causado por un error se puede medir como el impacto del mismo por el tiempo sin ser detectado. Hay que encontrarlos en cuanto ocurran, corregirlos, testearlos y actualizar la versión en producción.
    • Ampliar el aprendizaje
      Hay que incrementar el feedback con el usuario,
      para poder determinar con la mayor exactitud posible lo que desea y para resolver los problemas complicados que se presenten. Esto derivará en que la funcionalidad que se desarrolle sea exactamente lo que el usuario deseaba y que la utilice, de esta forma se puede eliminar alguna fuente de despercidio.
      Se puede, por ejemplo, mostrar al usuario los bosquejos de las pantallas de la aplicación y así tener su punto de vista, no solo del diseño visual, sino también de la funcionalidad.

      También es necesario incrementar el feedback dentro del equipo de trabajo, lograr que todos los involucrados conozcan el problema y participen en la resolución.
      Por ejemplo, se pueden hacer tests periódicos para detectar rápidamente cuando un proceso no funciona. Esto nos permite aprender mediante la experimentación.

    • Decidir lo mas tarde posible
      La idea no es aplazar la toma de decisiones, sino poder
      tomar una decisión en el momento de mayor certeza, así la misma estará basada en conocimiento concreto, no en especulación.

      La idea es esperar hasta el momento en que se encuentre disponible la mejor y mayor información. De esta forma, se evitarán cambios en la etapa final del desarrollo, y se bajarán los costos del mismo.

      Por ejemplo, antes de desarrollar una funcionalidad de diferentes formas, es mejor comunicarlas y decidir junto al usuario.

    • Entregar lo mas temprano posible
      Hacer entregas de funcionalidad rápidamente tiene muchas ventajas:
      El usuario tiene la funcionalidad que necesita cuando la necesita
      Se tiene un feedback más confiable por parte del usuario
      Se puede retrasar la toma de decisiones: se pueden tener varias opciones hasta estar mejor informado.
      Es mas claro, para el equipo de trabajo, de qué forma contribuir más efectivamente: pueden resolver qué hacer y cómo por si solos..

    • Dar poder al equipo
      Se le da prioridad a la gente y a los equipos de colaboración por sobre los procesos.
      Al reconocer que las personas que realizan el trabajo son las que conocen los detalles, se focaliza en métodos de formación de equipos para que puedan resolver sus propios problemas. Se los involucra en la toma de decisiones, de esta forma se logra que cada integrante el equipo se sienta participe del proyecto y la organización, y, por lo tanto, usen su potencial al máximo.
      El líder del equipo se encargara de marcar el objetivo, establecer ciertas pautas de trabajo, ser el guía.

    • Construir Integridad
      Se pueden encontrar
      2 clases distintas de integridad: Perceptiva, Conceptual.
      La integridad perceptiva tiene que ver con la percepción que tiene del cliente del sistema, cuanto mas a gusto este y cuanto mas cercano sea a sus exigencias y requerimientos, mas alta será la integridad perceptiva.
      La integridad conceptual significa que el concepto central del sistema trabaje en conjunto, como un todo cohesivo, y es un factor crítico que impacta en la integridad perceptiva.
      Otro nivel de integridad para el software es aquel que esta relacionado con la adaptabilidad del mismo en el futuro. Un software con integridad tiene una arquitectura coherente, se ajusta a los propósitos, es mantenible, adaptable y extensible fácilmente.
      La integridad se puede lograr con un sabio liderazgo, comunicación efectiva y una disciplina saludable.

    • Ver el Todo
      La integridad, en sistemas complejos, require una profunda experiencia en diversas areas. Uno de los problemas mas difíciles a tratar en el desarrollo de un producto es que los expertos en alguna area especifica tienden a maximizar la performance de la parte del producto que representan, en lugar de hacer foco en la performance del sistema en gral. Esto se denomina Sub-Optimización. El desafio es implementar practicas que la eliminen.

    Conclusión

    La aplicación de los principios Lean en el desarrollo de software permite mejorar los procesos y asi obtener mejores resultados.

    Aumenta la calidad del producto, posibilitando bajar los costos y acortar los tiempos de desarrollo.

    Estos principios son una guia, son algo general y universal, las metodologias agiles serian la forma de aplicar esta guia en la practica, indican qué hacer, adaptadas al dominio.

    Lo importante es poder entender y adoptar la escencia de los principios Lean. Es claro que su aplicación puede ser dificil en algunas companias, ya que requiere un cambio importante en la cultura y en los habitos organizacionales. Pero las mejoras que se pueden lograr son importantisimas, no solo en el producto final sino tambien en su evolución, en la participación, compromiso y satisfacción de las personas involucradas.


    Para leer mas sobre LSD y como aplicarlo: "Lean Software Development: An Agile Toolkit", autores: Mary y Tom Poppendieck.

    Leer más...

    De XP, Scrum, RUP, CMM(I), Crystal Clear y otras yerbas



    En la búsqueda de cómo optimizar nuestra forma de trabajo, nos encontramos frecuentemente ante la duda de "qué metodología aplicamos". Para dar respuesta a esa pregunta, y sabiendo de antemano que queremos movernos dentro de prácticas ágiles, nos fue útil tratar de conocer, evaluar y en algunos casos, ensayar, distintas alternativas.

    Por el momento optamos por seguir algunas de las directivas propuestas por Crystal Clear, pero entendemos que el proceso de decidir qué metodología implementar es un trabajo constante y debe responder a las necesidades del negocio y al crecimiento del equipo.

    Sin ser especialistas en el tema, describimos brevemente algunas comparaciones entre Crystal Clear (http://ideas3p.blogspot.com/2007/02/ms-all-de-las-capacidades-tcnicas-que.html) y otras metodologías.

    eXtreme Programming (XP)

    Crystal Clear comparte algunas características con XP (iteraciones cortas, entregas frecuentes, contacto directo con usuarios) pero es un poco menos demandante, es un buen punto de comienzo antes de lanzarse a abordar XP.

    • Las iteraciones en XP deben ser más cortas: de 1 día a 1 mes y no propone reglas sobre la duración de cada ciclo, a diferencia de CC que requiere que las entregas no se extiendan más allá de 3 meses, pero permite que la iteración pueda ser tan larga como el entregable.
    • XP requiere pair programming, CC no. Esto es porque XP apunta reducir el grado de libertad en las elecciones técnicas de los miembros del equipo para hacer las decisiones más efectivas. CC es más tolerante y flexible permitiendo al equipo adecuar sus propias convenciones a cada proyecto.
    • XP requiere tests automatizados con un gran conjunto de unit tests e integraciones varias veces al día. CC sólo recomienda lo primero y el período de integración puede variar según la complejidad de cada proyecto.
    • XP requiere un usuario como miembro del equipo, mientras que CC sólo promueve el “fácil acceso a los usuarios clave” con un mínimo de 1 hora a 1 semana de tiempo. Se busca el tiempo mínimo que permita satisfacer la seguridad del proyecto.
    • XP habla explícitamente de “simplicidad en el diseño y refactoring” como parte del largo término del desarrollo (a lo largo de todo el proceso). CC lo recomienda en las estrategias “Walking Skeleton” y “Rearquitectura Incremental”. Si bien CC aboga por diseños simples y refactoring, la duda es si esto tiene que ser un estándar de la metodología.
    • XP no requiere casi documentación, CC si. En términos de los 2 objetivos principales del “modelo de juegos cooperativos”

    Scrum

    Scrum se focaliza en 3 prácticas (además de tener a la comunicación como uno de sus pilares).

    • Time-Boxing: el subconjunto de requerimientos a ser desarrollados durante cada iteración se “congela” al principio de las mismas. Esto permite al equipo trabajar concentrados en los temas sabiendo que los mismos no van a cambiar.
    • Dynamic backlog: para compensar este “congelamiento” de requerimientos durante cada iteración, se lleva una lista de todo lo que resta por hacer. Esta lista puede cambiar cada vez que sea necesario. Al inicio de cada período el equipo revisa la lista, reprioriza los requerimientos, selecciona los que se van a desarrollar en esa iteración y los “congela” nuevamente.
    • Reuniones diarias: el equipo se reune cada día en una reunión muy rápida para comentar qué hizo el día anterior, qué va a hacer ese día y qué le resta por hacer.


    Estas tres técnicas serían el paralelo de las tres principales prácticas de Crystal (entregas frecuentes, comunicación, reuniones de reflexión).


    RUP (Rational Unified Process)

    RUP es similar a Crystal en cuanto a su estructura. Ambos son “generadores de metodologías”
    Los dos coinciden en que no hay un único proceso a aplicar en todos los proyectos.

    Ambos recomiendan un crecimiento incremental de la aplicación usando desarrollo por iteraciones, buenas prácticas de testing, contacto cercano y feedback con los usuarios y manejo de riesgos.


    Pero las diferencias de base se encuentran en los siguientes puntos:

    • RUP requiere definir una arquitectura, modelaje visual y uso de herramientas como puntos fundamentales. Crystal considera la arquitectura como propia de cada proyecto. Para el caso del modelaje visual, Crystal propone que el grado de detalle de la documentación es propio de cada proyecto y la documentación debe ser considerada como soporte y no como guía. Además, Crystal no cree en la necesidad de basarse en herramientas, sobre todo cuando éstas se usan para modelar.
    • Así como Crystal sostiene que cada metodología que se genere debe ser lo más simple, llana y eficiente que sea posible, RUP no declara la necesidad de características como estas.

    CMM(I) - Capability Maturity Model Integration

    Partiendo de la base que Crystal Clear no fue pensado para cumplir los requerimientos de CMM(I), muchas de las actividades que propone también son invocadas desde CMM(I), teniendo en cuenta que una de las principales diferencias es que Crystal se focaliza en proyectos mientras que CMM(I) apunta a organizaciones.

    Por otro lado, pensar que una organización que certifica en CMM(I) pueda incorporar algunos puntos impulsados por Crystal es altamente probable, y puede ayudar a incrementar su eficiencia

    Por ejemplo, ubicar al equipo en un espacio que permita una fuerte comunicación o adoptar las reuniones de reflexión no violan ninguna de las reglas de CMM(I). Tampoco lo hacen el apuntar a lograr seguridad personal, el tener fácil acceso a los usuarios expertos, el lograr un entorno tecnológico con testing automatizado o la práctica de integraciones frecuentes. Algunos puntos pueden llevar más trabajo, pero son totalmente aplicables.

    Evidentemente una de las mayores diferencias reside en que CMM(I) está soportado por una organización que capacita y actúa como evaluadora, cosa que no ocurre con Crystal.

    Y qué hacemos con todo esto ?

    En nuestra experiencia de pequeña empresa "con inquietudes de hacer las cosas mejor", por el momento nos volcamos a tomar ciertos aspectos de algunas de estas metodologías ágiles, sin ajustarnos estrictamente a una en particular y siguiendo fundamentalmente la regla principal de Crystal Clear de evaluar en cada momento y para cada proyecto, qué herramientas conviene aplicar.

    Suponemos que una evolución natural de la empresa y del equipo nos irá orientando a la adopción de prácticas más formales, como puede ser CMM(I), pero seguramente al momento de elegir cómo encarar nuestros trabajos seguiremos valorando la posibilidad de flexibilidad por encima de otras capacidades.

    Para consultar a los que saben:

    XP: http://www.salias.com.ar/articles.asp ; http://www.agilealliance.org/

    Scrum: http://www.scrumalliance.org/

    RUP: http://www-306.ibm.com/software/rational/

    “Crystal Clear – A human powered methodology for small teams”, de Alistair Cockburn http://alistair.cockburn.us/index.php/Crystal_methodologies_main_foyer

    Leer más...

    C# null coalescing operator

    A partir de la versión 2.0 de .NET, aparece para c# un nuevo operador "??", que es muy útil.

    Este nos permite devolver el valor que nosotros queramos, cuando una variable por ejemplo es Null, similar al isnull() del Transact-SQL.

    La forma de utilizarlo es muy simple veamos un ejemplo:

    Al utilizar esta Clase si queremos leer la propiedad Nombre y esta no fue asignada previamente, devolverá el mensaje de Nombre no disponible.

    public class Persona
    {
    private string nombre;

    public string Nombre
    {
    get
    {
    return nombre ?? "Nombre no disponible";
    }
    set
    {
    nombre = value;
    }
    }
    }

    Cabe aclarar que este operador solo puede utilizarse con Tipos que acepten valores nulos.
    Leer más...

    Novedades en Enterprise library 3.0

    viernes, 13 de abril de 2007

    Esta versión incluye dos nuevos “application blocks” llamados “Validation Application Block y “Policy Injection Application Block”. Dos guías y un editor de configuración que esta integrado con visual estudio. También fueron incluidas nuevas funcionalidades en el bloque de acceso a datos y en el manejo de logueo en una aplicación.

    Cambios que afectan a todos los bloques de aplicación


    • Incluye assemblies precompilados de todo el código.
    • El código de Enterprise library esta provisto por un archivo de instalación (.msi) que permite la extracción del código y la ubicación del mismo en un directorio especificado por el usuario.
    • Las extensiones de gestión y el parche “The partial trust patch 2554” fueron incluidos en el corazón de Enterprise library 3.0.
    • Es posible utilizar Visual Studio, para crear y modificar archivos de configuración. Este editor de configuración que la consola de configuración individual, pero esta herramienta utiliza la ventana de propiedades de Visual Studio para mostrar las propiedades de los bloques de la aplicación y muestra los posibles errores incluidos en la lista de errores al compilar la aplicación. Ahora es posible utilizar la consola y el editor de configuración para crear y modificar las ya conocidas secciones o adaptar la configuración de un bloque de la aplicación a un ambiente de explotación en particular.
    • Existe la posibilidad de encriptar y desencriptar los datos de configuración de la aplicación.

    Cambios que afectan a un bloque de aplicación en particular


    Data Access Application Block

    • Este bloque ahora incluye una nueva clase llamada “SqlCeDatabase” que permite utilizar SQL Server Compact Edition (ce), una versión liviana de SQL Server que incluye las funciones esenciales de un gestor de bases de datos relacional.
    • Incluye una nueva sobrecarga del método “Database.UpdateDatabase” método que utiliza el parámetro “updateBatchSize”. Asignándole a este un valor entero positivo, obliga al objeto “DataAdapter” a transmitir paquetes de un tamaño determinado pudiendo de esta manera reducir el numero de idas y vueltas al servidor.

    Exception Handling Application Block

    • Este bloque puede ser utilizado para poner en práctica la protección de excepciones en la interfaz con una aplicación de Windows Communication Foundation (WCF). El “ExceptionShieldingAttribute” puede invocar una política de excepción en la clase de implementación de un servicio. Y FaultContractExceptionHandler puede ser usado para captar excepciones por faltas al contrato de la política de seguridad e impedir que información sensible del sistema vuelva como mensaje de error a una llamada insegura.
    • El método “ExceptionPolicy.HandleException” incluye una nueva sobrecarga que permite atrapar una excepción y devuelve un parámetro de salida con el mensaje de la excepción, en vez de producir una falla.
    • Los manejadores de excepciones “Wrap” y “Replace” incluyen las propiedades de configuración adicionales que permiten especificar mensajes de excepción en recursos externos en vez de directamente en un archivo de configuración.

    Logging Application Block

    • Ahora incluye un “Rolling Flat File Trace Listener” mantiene archivos de log de un tamaño predeterminado. Comienza escribiendo un archivo de log y cuando este llega al tamaño máximo predefinido lo cierra y comienza uno nuevo.
    • Incluye un adaptador para Windows Communication Foundation (WCF) que permite generar un log de mensajes provenientes de una aplicación generada con esa tecnología.
    • Incluye una versión extendida de la clase “TimeStampToken”. Anteriormente solo se permitía que el “TimeStamp” fuera guardado en coordenada de tiempo universal, pero ahora tiene un prefijo local que indica que debe ser guardado de acuerdo a la configuración horaria local.
    • También incluye desde ahora una clase llamada “ReflectedPropertyToken“. Que permite dar un formato especificado por el usuario para los objetos de clases propias, antes de escribirlas en el archivo de log.

    Nuevos recursos en Enterprise Library 3.0

    Esta nueva versión incluye dos nuevos bloques de aplicación (Validation Application Block Y Policy Injection Application Block ) dos paquetes de guías (strong-naming guidance package y Application Block Software Factory ) y un editor de configuración que es integrado a Visual Studio.

    The Validation Application Block

    Permite al desarrollador crear reglas propias de validaciones para sus aplicaciones y lograr los siguientes beneficios

    • Proporciona un acercamiento común a la definición de reglas de validación para los objetos de negocios que les permiten ser reutilizados a través de las diferentes capas de las aplicaciones.
    • Proporciona un juego de reglas de validación comunes y da la posibilidad al desarrollador de definir sus propias reglas fácilmente.
    • Provee adaptadores de tecnologías que permiten integrar a este bloque en aplicaciones de ASP.NET, Windows Forms y WCF.

    The Policy Injection Application Block

    Este bloque permite especificar un comportamiento que corta transversalmente a las capas de una aplicación, obligando a los objetos de todas ellas respetar una política definida. Este comportamiento es utilizado cuando tareas, propiedades y/o procesos son comunes para diferentes objetos, como por ejemplo la autorización, validación e instrumentación necesaria para realizar una tarea en particular. El objetivo de este bloque es separar el corazón de la aplicación de los intereses transversales a las capas de la misma y reducir al mínimo los problemas relacionados con la asociación en la implementación de propiedades comunes entre ambas.

    Proporciona una solución prefabricada que es fácil para poner en práctica en usos nuevos y existentes, y en particular en usos que ya aprovechan “Enterprise Library”. Esto acelera el desarrollo ayudando a manejar preocupaciones que cortan transversalmente la aplicación.


    The Strong-Naming Guidance Package

    Este lanzamiento incluye una guía de nombramiento que se integra a Visual Studio. Esto automatiza el proceso de conexión de proyectos y modifica el atributo “InternalsVisibleTo”, para incluir una llave pública.


    The Application Block Software Factory

    Provee una guía escrita y automatizada que simplifica el proceso de creación bloques de aplicación propia o provista. Incluye recetas de automatización de dirección para una variedad de tareas, como lo siguiente:

    • Crear nuevos bloques de aplicación.
    • Crear nuevos proveedores de librerías.
    • Crear nuevos proveedores para los bloques de aplicación de “Enterprise Library” tipados o no tipados.
    • Crear nuevos proveedores genéricos tipados o no tipados.
    • Conversión de proveedores no tipados en tipados.
    • Crear nuevos proveedores de clases base.
    • Etc.

    Migración desde una versión anterior

    En general cualquier aplicación creada usando Enterprise Library 2.0 funciona sin necesidad de ningún cambio de código. Será necesario refrescar las referencias hacia los nuevos assemblies y los archivos de configuración para hacer referencia a la versión correcta de los mismos.

    Desde la página de MSDN se podrá obtener mayor información para realizar el cambio de 2.0 a 3.0 de las librerías para cada bloque en particular.

    http://msdn2.microsoft.com/en-us/library/aa480453.aspx
    Leer más...

    Detección automática de un Web Proxy

    martes, 10 de abril de 2007

    Muchas veces hemos visto en programas de escritorio que se conectan a Internet, la opción “utilizar la configuración de Internet Explorer”, esto por lo general se utiliza para tomar de éste la configuración de un web Proxy.

    Cuando se configura un proxy en Internet Explorer, esto se almacena en el registro de Windows, y podemos acceder a esta información desde .NET a través de la clase WebRequest.



    Ejemplo

    A modo de ejemplo puntual voy a mostrar un “caso de estudio” con el que nos encontramos recientemente. Este fragmento de una aplicación debe descargar desde nuestro blog los últimos artículos publicados e insertarlos en un DataSet para luego mostrarlos apropiadamente.

    Para esto se descarga un listado RSS (un archivo xml con el resumen de los artículos del blog) de la web (via http), que luego es parseado y recorrido para construir el DataSet deseado.

    Para esto creamos un HttpWebRequest cuya respuesta es utilizada para construir un XmlDocument, luego los nodos de este xml son recorridos con un simple foreach.



    Problema

    El problema surge al resultar imposible acceder directamente al servidor de nuestro blog desde la máquina donde corre esta aplicación, necesitamos utilizar el Proxy local. No resulta viable fijar este dato en nuestro app.config obligando a mantener este dato actualizado en cada instalación.





    Solución





    La línea interesante aquí es:

    A partir del Framework 2.0 de .NET en el namespace System.Net la clase WebRequest incorpora el método estático GetSystemWebProxy() que devuelve el Proxy configurado en Internet Explorer para el usuario impersonado. Y podemos así asignar programáticamente este Proxy al Request creado.

    Un punto importante a destacar es que esta configuración es dinámica, puede por ejemplo pasar por alto el Proxy si la URI indicada pertenece a un servidor local (si así se indica en la configuración de Proxy en Internet Explorer).

    Si la detección automática del Proxy falla, se utiliza el Proxy estático (si se estableció uno). Finalmente si todo esto falla, se intenta la conexión directa.

    Conclusión

    esta práctica nos permite olvidarnos de la detección o configuración de Proxys en nuestro código, y simplificar la molestia tarea de configuración y diagnostico de problemas en la conexión a Internet.



    Más información

    Sobre la detección automática de Proxys:
    Leer más...

    Introducción a Indigo (WCF)

    viernes, 23 de marzo de 2007


    Qué es Indigo (o WCF)?


    WCF, Windows Communication Foundation (se pronuncia Indigo), es la solución integral para sistemas distribuidos que forma parte de .NET 3.0, en particular para la implementación de arquitecturas SOA.

    WCF permite describir, publicar, implementar y consumir servicios, no solo con la interoperabilidad de los Web Services entre plataformas servidor y cliente, sino también utilizando diferentes plataformas de transporte de forma transparente al resto de la arquitectura.

    Una forma de introducir brevemente que nos "trae de nuevo" WCF es mediante estos 3 puntos:



    1. Uno para todos y todos para uno

    WCF Integra diversas plataformas de comunicación preexistentes para sistemas distribuidos bajo una capa de abstracción

    Para la construcción de sistemas distribuidos Microsoft tenía ya distintas tecnologías cada una con sus ventajas y desventajas, Indigo pretende incorporar varias de ellas y "esconderlas" detrás de un modelo de servicio. Esto significa que podemos evitar (o posponer) la decisión clave de escoger el tipo de transporte al momento de diseñar la arquitectura de nuestra solución.

    Las tecnologías de comunicación preexistentes que WCF engloba son:

    - ASP.NET Web Services (incluyendo las WSE, Web Service Enhancements)
    - Microsoft Message Queue
    - Enterprise Services/COM+
    - .NET Remoting

    Una gran promesa de WCF es poder intercambiar, combinar (y extender, puntos 2 y 3) cualquiera de éstas tecnologías en nuestros servicios, dejando la posibilidad de aprovechar los puntos fuertes de cada una según sea apropiado en el entorno de nuestra aplicación. Esto significa también el ahorro de horas dedicadas al dominio de cada tecnología particular.



    2. Extensibilidad

    El comportamiento de los servicios WCF puede extenderse con distintos grados de granularidad

    La principal muestra de extensibilidad se da en la posibilidad de definir "Behaviors" e "Inspectors"

    Los Behaviors, como su nombre indica, permiten extender, según se desee, el comportamiento de un servicio, una operación que ofrece un servicio, o un Endpoint.

    Endpoints

    Un Endpoint representa un punto de acceso donde un servidor recibe clientes, se define mediante un terna "ABC":
    • Address, dirección (una url, un puerto TCP, etc)
    • Binding (Tcp, Http, Pipes, etc)
    • Contract (descripción del servicio, de las operaciones disponibles, tipos de datos, etc)

    Así un servicio puede ser expuesto en múltiples Endpoints, un ejemplo típico sería el de un servicio disponible vía Web (un Endpoint con Binding Http, o wsHttp) y vía Intranet (usando un EndPoint con Binding TCP) simultáneamente.


    Los Behaviors permiten "colgarse" de diferentes sucesos en la vida de un servicio (en el pipeline de WCF), en la invocación de una operación, o en el procesamiento de los mensajes entrantes y salientes. Muchas veces se usan los Behaviors para colgar un Inspector que realiza el verdadero trabajo.

    Un ejemplo típico es la interfaz IParameterInspector, ésta declara los metodos "BeforeCall" y "AfterCall" que se invocarán antes y después de la ejecución de una Operación determinada, permitiendo en ese momento validar parámetros, o verificar la autorización de usuario cliente, crear un log de las operaciones invocadas, o simplemente debuguear.

    Estas extensiones, tanto Behaviors como Inspectors pueden "engancharse" decorando con atributos la descripción del servicio, programáticamente, o en archivos de configuración. Esta opción triple para definir o configurar un servicio es característica en WCF, cada modo claramente es útil a distintos fines.




    3. WS-*

    Los servicios de WCF implementan las WS-*, agregando métodos de seguridad y enrutamiento de forma nativa

    Estas extensiones (análogas a las WSE, de los Web Services ASP.NET) apuntan principalmente a la integridad y confidencialidad de los mensajes, direccionamiento, garantía de entrega y transaccionabilidad.

    WS-Security, WS-Policy, WS-Trust, WS-Addressing, WS-SecureConversation, WS-ReliableMessaging, WS-AtomicTransaction, WS-Coordination

    Esto significa un gran abanico de opciones de autenticación, encriptación, y enrutamiento de los mensajes.



    Links para seguir leyendo:

    • Introduction to Building Windows Communication Foundation Services
    http://msdn2.microsoft.com/en-us/library/aa480190.aspx
    • Windows Communication Foundation (Indigo) FAQ
    http://msdn2.microsoft.com/en-us/windowsvista/aa905015.aspx
    • Windows Communication Foundation (netfx3)
    http://wcf.netfx3.com/
    • Introducing Indigo: An Early Look
    http://msdn2.microsoft.com/en-us/library/aa480188.aspx
    • WCF Extensibility: Behaviors and Inspectors
    http://steve.emxsoftware.com/Indigo-WCF/WCF+Extensibility+Behaviors+and+Inspectors
    Leer más...

    Unit testing Buenas practicas

    Los tests unitarios son una herramienta que ayuda el desarrollo de aplicaciones en escenarios de trabajo formados por equipos donde cada uno tiene un rol definido. En este artículo hablaremos sobre prácticas recomendables a la hora de utilizar Unit Testing.

    Los tests de nuestros proyectos serán ejecutados por los desarrolladores y es a ellos en quien se debe pensar a la hora de crearlos, que sean amigables es una propiedad tan importante como que nuestros tests funcionen correctamente.

    Verdades relativas de los tests unitarios

    • La detección de errores se ve facilitada.
    • El código es fácil de mantener.
    • El código es más comprensible.

    Para que estas tres verdades se cumplan es necesario un buen desarrollo de tests unitarios. A continuación daremos una serie de recomendaciones útiles para lograrlo.

    Testear lo correcto

    Un test debe probar el que y no el como, debe asegurarse que la funcionalidad del código a probar se cumpla en forma correcta y no prestar atención a como lo logra.
    Hacer test sobre la interfaz pública de las clases nos permitirá generalmente probar toda la funcionalidad disponible en la misma, mientras que si hacemos test sobre los métodos privados y/o protegidos seguramente nos estaríamos involucrando en la forma en que están implementadas las tareas y no si el fin se cumple correctamente. Cumpliendo con esta premisa sortearemos fallas en nuestros test cuando por algún motivo halla cambios en como se realizó determinada tarea.

    Cuando un test falla en forma incorrecta

    A veces encontramos un test que falla incluso sabiendo que los cambios realizados en el código son correctos. Esto generalmente nos llevará a la conclusión de que hemos hallado requerimientos incompatibles. En esta situación podremos tomar dos caminos diferentes...

    1. Borrar el test, luego de verificar que no será válido nunca más, ya que el requerimiento que lo hizo necesario ya no es un requerimiento del sistema.
    2. Modificar el test antiguo para adecuarlo a los nuevos requerimientos. Generalmente agregando un nuevo test que modifique las condiciones iniciales o finales del mismo.

    Cobertura y ángulos de prueba

    Como saber si el código se encuentra suficientemente cubierto por los test? Una prueba básica y muy efectiva es eliminar una línea de código de una funcionalidad completa, en el caso de que hecho esto un test falle esa porción de código tiene razón de ser, de lo contrario, será necesario agregar un nuevo test. En el caso de llegar a esta situación y no encontrar la forma de hacer un test que falle al comentar el código, es muy probable que el mismo no sea necesario.
    Jamás sabremos cuando será necesario que otro programador modifique nuestro código, y si no se tienen los test necesarios para probar cada porción del mismo, no podrá notar si sus cambios perjudican otra funcionalidad que lo utilizaba parcial o totalmente
    Seguramente en muchos casos un método necesitará varias pruebas, todas bajo diferentes condiciones para asegurar su correcto funcionamiento, uno de los errores más recurrentes en la escritura de un test es intentar abarcar todas las opciones dentro de un mismo test, esto es inadmisible ya que estaríamos violando la regla básica de este método de prueba, como su nombre lo indica estamos haciendo “Test Unitarios”, es decir, cada test prueba una y sólo una cosa. Nos daremos cuenta cuando estemos infringiendo esta regla si nos encontramos escribiendo una sentencia if, while, Etc... Respetar esta regla nos ahorrará, probablemente, tiempo valioso en prueba de nuestros test.

    Los test deben ser sencillos de ejecutar

    Facilitar la ejecución de test hará que los desarrolladores, para quienes esto es solo una perdida de tiempo en sus primeras aproximaciones, no se resistan a la idea de que ejecutar los test les ayuda a ganar tiempo y a encontrar errores en el código más fácilmente.
    Existen básicamente dos tipos de test

    1. Los que pueden ejecutarse aleatoriamente.
    2. Los que necesitan una condición previa, para testear una situación en particular.

    La idea es que todos nuestros test formen parte del primer grupo, de no ser posible, deberíamos agrupar unos separados de los otros con el objetivo de tener una serie de test que cualquiera sea capaz de ejecutar y probar que la funcionalidad básica esta cubierta y funcionando correctamente y otro grupo que pruebe más exhaustivamente que corramos menor cantidad de veces.
    Los test del primer grupo se ejecutarían todo el tiempo, ante cualquier cambio por menor que sea, mientras que el segundo, después de haber completado la implementación de determinado requerimiento.

    Desarrollo y mantenimiento

    El test unitario debe ser escrito antes de programar una nueva funcionalidad o al modificar una que aún no tenía su test, no hay que confundirse en este paso el punto más importante en el comienzo de la generación de nuestros tests, “Los test deben fallar solo cuando la funcionalidad esté incompleta o no cumpla con los requerimientos”, comprender bien este punto nos ayudará a no hacer test que fallen por estar probando cosas ilógicas.
    Un test creado no debe ser eliminado, sólo se llevará a cabo esta acción cuando los requerimientos sean modificados y la funcionalidad ya no sea requerida.

    Eliminación de dependencias entre test

    Anteriormente hablamos de dos grupos de test y las ventajas de tener test independientes que no necesiten un estado para salir airosos en su ejecución. Dos sentencias que ayudan bastante a esto son “TestInitialize” y “TestCleanup” que ayudan a mantener frescas todas las instancias de las clases utilizadas en nuestros test.
    El método “TestInitialize” es el lugar donde debe encontrarse el código necesario para generar el estado básico para la ejecución de todos los test de una clase, si solo para uno de estos, parte del código no es relevante, no debería estar ahí. En estos casos es posible y recomendable, escribir un método de inicialización que se llame desde un test en particular, así estaríamos también modularizando el código, lo que nos facilitará la reutilización del mismo.

    No incluir más de un ASSERT por test

    Aparte de no estar reutilizando el código en nuestros test, esto nos hará perder más tiempo del necesario en resolver los problemas que detecten los mismos por los siguientes motivos. En primer lugar, cuando una sentencia assert falla se detiene la ejecución del método y por lo tanto las posteriores sentencias no serán ejecutadas y quizás fallen en el próximo intento. Necesitando así varias corridas de un mismo test para solucionar todos los problemas que era capaz de detectar. Eliminando la acumulación de estas sentencias en nuestros test no solamente nos libraremos de este problema, sino que, el tener de una vez la mayor cantidad de errores posibles nos ayudará a tener una idea más abarcativa del posible problema.

    Crear test legibles

    Hay un par de puntos básicos a seguir para lograrlo, dividir expresiones complejas en varias más sencillas y llamar a cada ítem con un nombre representativo a su funcionalidad dentro del código.
    Aprender a nombrar cada ítem puede ser muy difícil pero sin duda es un punto más que importante a la hora de que el código sea legible y más aún a la hora de escribir test ya que con mirar el error que se detecta en uno de ellos deberíamos ser capaces de comprender que causó la falla y poder solucionarlo.
    El nombre de un método de test se podría dividir en tres partes, el nombre del método bajo prueba, el estado o regla a probar y la salida esperada del mismo. No debería incluirse “Test” y/o el nombre de la clase bajo prueba ya que seguramente esto forma parte del nombre de la clase a la cual pertenecen nuestros test. Siguiendo estas reglas es probable que tengamos nombres mucho más largos que de costumbre pero no será relevante si esto ayuda a ganar tiempo cuando este apremia, a la hora de corregir bugs.

    Conclusión

    Como pudimos ver en este pequeño informe, escribir test no es una tarea trivial ni sencilla. Si bien escribir un test unitario no es más complicado de lo que es hacerlo con cualquier otro método y/o clase, para poder sacar provecho de la utilización de los mismos debemos tener en cuenta muchos aspectos que ayudarán a lograr mayor productividad utilizándolos. De lo contrario, no solo perderemos tiempo en escribirlos, sino también, en mantenerlos, correrlos, resolver los problemas por estos detectados y más.

    Finalmente, la utilización de test puede ser de muchísima ayuda a la hora de producir y mantener una aplicación, solo debemos tener en cuenta que esta tarea no es sencilla y debemos prestar mayor atención en la redacción de los mismos.

    Leer más...

    Windows Workflow Foundation

    jueves, 22 de marzo de 2007


    ¿Que es Windows Workflow Foundation?

    Windows Workflow Foundation es el modelo de programación de Microsoft que permite crear aplicaciones con funcionalidad de workflow. Consiste en un motor de workflow embebido y un add-ins para el entorno de desarrollo de Visual Studio 2005.

    Un workflow es un conjunto de actividades guardadas como un modelo que describe un proceso del mundo real. El trabajo pasa a través del modelo desde el principio hasta el final, y las actividades pueden ser ejecutadas por personas o por funciones del sistema.

    Las actividades pueden ser simples o compuestas. Una actividad compuesta es un conjunto de actividades simples.

    Seria totalmente posible escribir un workflow completamente en código, pero éste en general es mejor visto si es representado gráficamente.



    ¿Que puedo hacer con WWF?

    Windows Workflow Foundation soporta una amplia gama de situaciones de flujo de trabajo, incluyendo aplicaciones de línea de negocio, flujo de páginas de interfaz de usuario, flujo de trabajo centrado en documentos, flujo de trabajo humano, flujo de trabajo compuesto para aplicaciones orientadas a servicios, flujo de trabajo impulsado por reglas empresariales y flujo de trabajo para gestión de sistemas.

    Usando Windows Workflow Foundation, los desarrolladores pueden incorporar conceptos tales como scheduling, coordinación de tareas y escalabilidad en sus aplicaciones existentes sin costo alguno. WWF provee la plataforma base donde se pueden desarrollar aplicaciones con muchos procesos.


    ¿Cómo ejecuto un workflow?

    Una vez que el modelo es compilado, puede ser ejecutado dentro de cualquier proceso de Windows, incluyendo aplicaciones de consola y WinForms, Servicios Windows y Web, como también páginas ASP.NET o aplicaciones de servidor.
    Tambien en SharePoint y otros productos como Microsoft BizTalk Server y los servidores de Microsoft Office.

    Tipos de workflows

    Flujo Secuencial: Es aquel donde se ejecutan una serie de actividades en una secuencia predefinida. Esta secuencia puede incluir operadores de control de flujo similares a los que han existido durante años en lenguajes de programación. Por ejemplo, operadores de decisión (if…else) o de iteración (while). Se utiliza para flujos donde nos interesa que el control lo tanga primordialmente el proceso definido.

    Flujo de Máquina de Estados: En este flujo las actividades se ejecutan dependiendo de el estado en el que se encuentre una máquina de estados, así como de las transiciones entre estos estados (que pueden ser iniciadas por las actividades mismas). Se utiliza normalmente para flujos donde se prefiere que el control recaiga mayormente en los usuarios del sistema.
    Ejemplo


    Requisitos

    Microsoft .NET Framework 3.0 Redistributable Package
    http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en

    Visual Studio 2005 extensions for .NET Framework 3.0 (Windows Workflow Foundation)
    http://www.microsoft.com/downloads/details.aspx?FamilyId=5D61409E-1FA3-48CF-8023-E8F38E709BA6&displaylang=en

    Sitios de interés

    http://wf.netfx3.com/
    http://msdn2.microsoft.com/en-us/library/ms741723.aspx
    Leer más...

    TRY/CATCH en SQL 2005

    viernes, 9 de marzo de 2007

    Microsoft SQL Server 2005 trae incorporada una nueva forma de manejo de errores. Las versiones anteriores solo permitían el detectar errores con la función @@Error, que permite hacer un reporte del error pero no hacer un manejo, solamente muestra la información y la excepción se manda al que llamó al Stored Procedure y es él quien decide qué hacer.
    Otra desventaja del @@Error es que el empleo apropiado de esta función requiere hacer una comprobación después de cada declaración, de otra manera el valor de la variable se resetea.
    Por ejemplo:
    SELECT 1/0
    IF @@ERROR <> 0
    BEGIN
    SELECT @@ERROR
    END
    -----------
    Msg 8134, Level 16, State 1, Line 1Divide by
    zero error encountered.
    -----------
    0
    (1 row(s) affected)

    La función @@Error devuelve 0 en el select, y no el número de error, porque el IF no dio un error.

    En SQL Server 2005 las excepciones se pueden manejar desde el SP con la nueva función TRY/CATCH, que emula el manejo de errores derivado del lenguaje C. Se escribe el código dentro del bloque TRY y si lanza una excepción la recibe el bloque CATCH, de esta forma el error puede manejarse dentro del SP sin necesidad de mandar una excepción al que lo llama.
    Esta función también ayuda a mejorar el código de las transacciones ya que no hay que escribir la validación del @@Error después de cada declaración sino que desde el momento en que empieza la transacción se hace un TRY y en el CATCH se hace el rollback.

    Microsoft SQL 2005 también tiene otras funciones que facilitan el reporte de errores que son ERROR_MESSAGE(), ERROR_NUMBER(), ERROR_LINE(), ERROR_SEVERITY(), ERROR_STATE() y ERROR_PROCEDURE(). Estas funciones a diferencia del @@Error no se resetean.

    Un ejemplo simple del uso del TRY/CATCH con las funciones de ERROR sería crear un Store Procedure con el siguiente código:
    CREATE Procedure PruebaTryCatch
    (
    @Dividendo int,
    @Divisor int
    )
    as
    BEGIN TRY
    SELECT @Dividendo/@Divisor
    END TRY
    BEGIN CATCH
    SELECT
    ERROR_MESSAGE() as Mensaje,
    ERROR_NUMBER() as Numero,
    ERROR_LINE() as Linea,
    ERROR_SEVERITY() as Severidad,,
    ERROR_STATE() as Estado,
    ERROR_PROCEDURE() as Proceso
    END CATCH
    Si lo ejecuta con el número 1 como dividendo y el 0 como divisor:
    EXECUTE PruebaTryCatch 1, 0
    El resultado será:

    Mensaje                          Numero Linea
    -------------------------------------------------------
    Divide by zero error encountered. 8134 11

    Severidad Estado Proceso
    ------------------------
    16 1 PruebaTryCatch
    Leer más...