Tecnologías

TDD / DDD / IRepository / Patrones / NHibernate / NUnit / C# / Linq / Net 3.5 / BDO  2004-4-3 Regata Dr. Cingano a Colonia 026

Cómo manejo la persistencia de mi aplicación?

Tenemos la posibilidad de actualizarnos en temas de persistencia. Leyendo un artículo muy interesante de Rob Conery Crazy Talk: Reducing ORM Friction. En el mismo, Rob propone realizar la implementación de nuestra aplicación sin preocuparnos por los temas de mapeos con los ORM. Lo que nos propone es dediquemos al diseño a través del TDD (pensando en una orientación similar a la de DDD) de nuestra aplicación utilizando una implementación por medio de una base de datos orientada a objetos.

 

IRepository

Para ello y siguiendo con los conceptos de Domain Driven Design se elige el patrón Repository y se desarrolla la siguiente interfaz que nos va a permitir los distintos providers (implementaciones) que necesitamos para poder diseñar utilizando un modelo de Base de Datos  Orientado a Objetos y luego implementar los providers que necesitemos para ir a producción. con el ORM de nuestra preferencia. En este caso vamos a hacer la implementación de nuestro ejemplo con las elecciones de Rob, BD4O como base de datos orientada a objetos y LinqToSql como ORM. Al final veremos un poco la discusión sobre la ¨muerte de LinqToSql¨. En un próximo post buceo en la implementación del provider con NHibernate y las problemáticas de recorrer una expresión Linq para generar un Criterio de filtro para NHibernate.

using System;
using System.Linq;
using System.Linq.Expressions;
namespace Hover.Repository
{
    public interface IRepository<T>
    {
        IQueryable<T> GetAll();
        IPagedList<T> GetPaged(int pageIndex, int pageSize);
        IQueryable<T> Find(Expression<Func<T, bool>> expression);
        void Save(T item);
        void Delete(T item);
    }
}








DB4O



La opción que presenta Rob para la implementación del provider contra Base de Datos Orientada a Objetos es DB4O.


Lo primero que implementaremos en un helper que nos va a servir como ayuda para la comunicación con el motor de DB4o.


Básicamente es un singleton que nos devuelve una instancia de container para intractuar con la base de datos. Acá Rob, remarca constantemente que estamos realizando una implementación para la etapa de desa rrollo, que no vamos a estar preocupados por perfomance (de ahí a no preocuparnos por el momento por le Singleton!, que ya es mala palabra).


Una vez que tenemos el helper podemos comenzar con los tests de las implementaciones del Repository.



        [Test]
        public void CanSave()
        {
            // Arrange
            File
            IRepository<Person> repository = new Repository<Person>();
.Delete(DB4OHelper.DBPath);
            Person person = new Person { FirstName = "Chapita", LastName = "Velazquez" };
            // Act
            repository.Save(person);
            // Assert
            var result = from Person p in DB4OHelper.Container
                         where p.FirstName == "Chapita"
                         select p;
            Assert.AreEqual(1, result.Count());
            Person personFromDB = result
                .FirstOrDefault();
            Assert.AreEqual(person.FirstName, personFromDB.FirstName);
            Assert.AreEqual(person.LastName, personFromDB.LastName);
            // Just to chain the next test
            DB4OHelper.CloseContainer();
        }


El patrón que utilizamos para implementar TDD es AAA. Arrange / Act / Assert. Por lo tanto primero hay que realizar el setup Arrange, luego hacemos tdodo lo que nos interesa testear y por último realizamos los asserts. Por supuesto no olvidarse los conceptos de de TDD ROJO, VERDE, REFACTOR!.

Luego que nos de ROJO por los motivos esperados implementamos el método Save.




        public void Save(T item)
        {
            DB4OHelper.Container.Store(item);
        }






Les dejo como tarea testear, implementar y refactorizar los otros métodos.



Descargar el ejemplo



El ejemplo desarrollado se encuentra para descargar en google!!! En caso de no contar con Visual Studio 2008 se puede utilizar la versión express y correr los tests desde la consola de NUnit.



NetIRepository















Lo que sigue





En el próximo post voy a intentar implementar la misma interfaz del IRepository para utilizar primero desde LinqtoSQL y luego desde NHibernate, con los inconvenientes que tiene interfacer expresiones Linq con Criterios de NHibernate.

Luego inetntaré implementar los providers como servicios REST para usarlo desde Silverlight, WPF, Asp.Net MVC.



 













Fotos
12:08 | Author: Unknown
Ante la consulta... Si las fotos las sacamos nosotros (Ana y yo) en el Río de la Plata. Que ganas de estar navegando!
Python el regreso
10:02 | Author: Unknown

Modelo terminado

2004-1 Vacaciones en Uruguay 104 (1) El script (ver entrada anterior IronPython) como lo estoy utilizando. (usar el plugin de inserción del source code no fue tan sencillo)

  1: def matchversion(folder, major, minor, build):
  2: 	import os
  3: 	import re
  4: 	import datetime
  5: 	today = datetime.datetime.today()
  6: 	calculatedVersion = (today.year * 12 + today.month) * 100 + today.day
  7: 	for root, dirs, files in os.walk(folder):
  8: 		for file in [f for f in files if f == "AssemblyInfo.cs"]:
  9: 			pattern = '(AssemblyVersion\(\"(\d*|\*)\.(\d*|\*)\.(\d*|\*)\.(\d*|\*)\"\))'
 10: 			version = 'AssemblyVersion("' + str(major) + '.' + str(minor) + '.' + str(build) + '.' + str(calculatedVersion) + '")'
 11: 			arch = open(root + file)
 12: 			bytes = arch.read()
 13: 			replaced = re.sub(pattern, version, bytes)
 14: 	                  arch.close()
 15: 	                  arch = open(root + file, 'w')
 16: 	                  bytes = arch.write(replaced)
 17: 	                  arch.close()
Lo que necesitaba
9:45 | Author: Unknown

2004-1 Vacaciones en Uruguay 328

 

 

 

Genial esto es lo que estaba buscando para mejorar este blog, después del papelón publicando el post de Python, vuelvo al ataque.

Un plugin para el Windows Live Writer para insertar source code!! Link al autor

IronPython
3:53 | Author: Unknown

Tecnologías

IronPython /Python / .Net / Regular Expressions

Lo mejor de dos mundos ?2004-9-4_En_el_barco_con_los_amigos_032[1]

No se si estoy en lo correcto, hace un tiempo me puse como meta aprender Python, sólo creo que lo hice por ser fanático de los Monty Python, (acá es donde pongo una lista de gags históricos y se acabó el blog de tecnología).  Pero no, veo que existen muchos fanáticos, y poco a poco me voy dando cuenta porque.

Python Rules

Creo que para empezar tomé una mala decisión. El c# boy pensó ("El que piensa pierde!" Les Luthiers), dado que tenés un conocimiento importante del framework de .Net, porque no usas IronPython y te allanás muchos caminos? Sin embargo la historia no es tan fácil como lo pensaba. Y es acá cuando descubro el IDLE, el editor que viene en la versión de Python. Y aunque viniendo del "glorioso" Visual Studio y el ReSharper, etc. Me encuentro que este IDE recontra simple es lo que más me está ayudando para aprender Python.

Ejemplo

Como siempre que empiezo con algún lenguaje nuevo busqué una necesidad real (no me gusta empezar con vueltas de rosca a cosas hechas por mi mil veces). Y a embarrarse.
El problema es simple, pisar los AssemblyVersion de un producto con múltiples soluciones .Net para que reflejen una única versión.
Esto me obliga a: entender el manejo del file system, manejo de archivos, expresiones regulares y algo de cálculo (la versión es calculada)

  • Calcular versión

Para el cálculo de versión simplemente tomamos la major  y minor  (vienen provistas) y le calculamos la build version que es la cantidad de meses sumados los días del mes. Importando las librerías de .Net es muy sencillo.

 image
En versión Python estándar.
>>> import datetime
>>> dia = datetime.datetime.today()
>>> versionMinor = dia.year * 12 + dia.month * 100 + dia.day

  • Recorrer estructura de carpetas

>>> import os
>>> for root, dirs, files in os.walk('./mydir'):
                      for file in [f for f in files if f == "AssemblyInfo.cs":

Bonito!

  • Modificar versión

Para esto cargamos el archivo, y con una expresión regular cambiamos la versión por la calculada y reescribimos el archivo.

>>> import re
>>> for root, dirs, files in os.walk('d:/temp'):
                      for file in [f for f in files if f == "AssemblyInfo.cs"]:
                                 pattern = '(AssemblyVersion\(\"(\d*|\*)\.(\d*|\*)\.(\d*|\*)\.(\d*|\*)\"\))'
                                 arch = open(file)
                                 bytes = arch.read()
                                 print re.search(pattern, bytes)
                                 # replace
                                arch.close()

Código compacto, bastante legible. Y dado que me metí con las expresiones regulares viene cita.

Some people, when confronted with a problem, think "I know, I'll use regular expressions."
Now they have two problems.

−−Jamie Zawinski, in comp.emacs.xemacs

Lo que sigue

En la próxima termino el ejemplo y por otro lado voy a ver un poco los frameworks que podemos usar como por ejemplo Django.

Setup para una nueva aplicación
16:04 | Author: Unknown
Tecnologíasimage

CC.Net / Subversion/ TortoiseSVN / Commit Monitor / AnkhSVN /VS 2008 / Resharper /TestDriven / NUnit / Watin / TDD

Un poco de historia

Años atrás (y lamentablemente lo seguimos viendo), desarrollábamos aplicaciones en forma colaborativa. Nos íbamos pasando desarrollos entre programadores y de ésta forma íbamos sumando desarrollo y entregando al cliente. El proceso del desarrollo del software ha dejado de ser un insight artesanal para convertirse en un proceso ingenieril (sin embargo es interesante escuchar el panel de cierre de Ágiles 2008, donde entre otros Mary Poppendieck y Micah Martin proponían volver al craftsman, al artesano).
Cuantas veces escuchamos la famosa frase ¨En mi máquina funciona¨. Para eliminar estas problemáticas debemos utilizar distintas sencillas prácticas que nos permitirán armar un ambiente de desarrollo tal que no tendremos que preocuparnos por esos viejos problemas.

Repositorio

El repositorio nos permite mantener la información centralizada, mantener log, generar tags/branchs, volver a revisiones anteriores, etc.
Nosotros utilizamos Subversion y para el ejemplo que vamos a realizar crearemos un repositorio en code.google.com que nos provee como repositorio SVN.
Para administrar el  repositorio en forma local utilizamos TortoiseSVN, que nos integra el manejo de la copia en checkout del repositorio local con el explorer de Windows.
AnkhSVN nos realiza la integración del Subversion en Visual Studio.
Existen otras opciones que iremos analizando, mientras tanto se puede ver este artículo.

TDD

Nuestra forma de trabajar está basada en TDD (Test Driven Development). Hay mucho para investigar sobre el tema. Lo único que proponemos aquí es tener en cuenta el patrón RED, GREEN, REFACTOR. Esto es realizamos el test necesario para verificar una funcionalidad que estamos agregando a nuestra aplicación. Al no estar desarrollado el código que satisface el test, el mismo va a fallar por el motivo esperado, estaremos en rojo. Se  realiza el código que satisface el test, por lo tanto estaremos en verde. por último realizamos el refactor, que nos permitirá eliminar código repetido, innecesario, etc. Volvemos a probar los test que deberán seguir en verde.
Las herramientas que utilizamos son NUnit como framework de tests. Y para ejecutarlos desde el ambiente de Visual Studio utilizamos ReSharper (que también nos provee muchísima otra funcionalidad espectacular, es adictivo!) o TestDriven, un plugin gratuito.

CruiseControl

Cada desarrollador trabaja en una copia local del repositorio y realiza las modificaciones necesarias, en el momento que ha finalizado alguna parte de una tarea que se encuentra funcional decide subir al repositorio. Para ello verifica que su aplicación compile, corre los test unitarios y de aceptación que corresponden y luego realiza commit al repositorio (si es necesario llevar un control en tiempo real de los commits se puede recurrir al Commit Monitor) .
Una vez que se sube al repositorio, contamos con el CruiseControl .Net que es el encargado de realizar las mismas tareas en el ambiente de integración. 
Decargará todo lo necesario del repositorio, verificará triggers, colas, prioridades, realizará las tareas de compilación, correrá test unitarios, test de aceptación, puede correr aplicaciones de verificacion como el FXCop, NCover, NDepend, etc.
Recién luego de todas éstas tareas estamos seguros que tenemos una aplicación integrada correctamente.
Existe una herramienta complementaria CCTray, que nos permite ver en el Tray el estado en que se encuentra la integración de la aplicación en forma constante. Es necesario tener reglas claras para mantener el repositorio en verde constantemente.

 

Watin

Este framework nos permite realizar test contra la web. Utilizamos nosotros esta herramienta dado que nos permite realizar tests unitarios (usando NUnit) por medio de COM obtenemos una instancia del browser y probamos la funcionalidad , no sólo, el alcance de nuestras interfaces. Esto también lo integramos al CC y lo verificamos en un night test.

Comentarios

Espero recibir comentarios, es sólo una forma de trabajar. Espero poder ampliarlo con ejemplos de cada una de las aplicaciones. para primer post está bien!

Hover Over Technologies
16:14 | Author: Unknown
 2004 vacaciones enero Uruguay 018

Intentando flotar sobre las tecnologías. Los últimos años nos vamos dando cuenta que ya no nos alcanza dominar una técnica, una metodología o una forma de trabajar, hoy voy a mostrar otro camino, el mío.