A propósito del ProjectEuler
8:49 | Author: Unknown

Para la resolución del primer problema del Proyecto Euler hice un extension method:

public static class IntExtension
{
public static bool IsMultiplesOf (this int number, int multiple)
{
return (number % multiple) == 0;
}
}


Y su uso es tan simple como



i.IsMultiplesOf(3)

Project Euler
8:35 | Author: Unknown

2006-6-3 al 5 Fotos en casa nueva 019 Un sitio muy interesante para probar nuestras capacidades comprendiendo problemas y la solución de los mismos en los diferentes lenguajes de programación que conocemos o que deseamos conocer.
Proyecto Euler tiene como objetivo mostrarnos diferentes problemas matemáticos o computacionales que deberemos resolver. A pesar que una persona con mayores conocimientos matemáticos podrá resolver algunos de los problemas sencillamente, para la solución de los mismos se requiere del uso de software.
A modo de prueba la solución de los dos primeros no me demoro en C# más de 10 minutos. Ahora para complicarme un poco más las cosas voy a intentar resolver los siguientes en Python y aprovechar para probar un poco de Ruby 

Tecnologías

TDD / DDD / IRepository / Patrones / NHibernate / NUnit / C# / Linq / Net 3.5 / BDO 

Linq to SQL

Está muerto ?Colonia

Aparentemente Microsoft esta dejando de lado LinqToSql  por su variedad en esteroides Entity Framework (voy a ver si puedo traducir este post al E/F). Un buen punto de partida sobre esta discusión es blog del buen Ayende (mucho tiempo con colombianos, ya digo "el buen", jaja) y en particular este post.


Helper?

Lo primero que debemos hacer es agregar al proyecto de implementación un ítem del tipo Linq to Sql classes. Y allí utilizando el editor crear el contexto con nuestras clases.

En el caso de la implementación para LinqToSql utilizamos en vez de un helper métodos en la implementación que nos proveen el DataContext y las tablas.

    public class Repository<T> : IRepository<T> where T : class
    {
        private DomainDataContext domainDataContext = null;
        public Repository()
        {
            domainDataContext = new DomainDataContext();
        }
        /// <summary>
        /// Gets the table provided by the type T and returns for querying
        /// </summary>
        private Table<T> Table
        {
            get { return domainDataContext.GetTable<T>(); }
        }








Tests de la implementación de LinqToSql









Testando los diferentes métodos del Repositorio.









        [Test]
        public void CanSave()
        { 
            // Arrange
            IRepository<Person> repository = new Repository<Person>();
            ResetDB(repository);
            Person person = new Person { FirstName = "Chapita", LastName = "Velazquez" };
            
            // Act
            repository.Save(person);
           
            // Assert
            Person personFromDB = repository
                .GetAll()
                .Where(p => p.FirstName == "Chapita" && p.LastName == "Velazquez")
                .FirstOrDefault();
            Assert.AreEqual(personFromDB.FirstName, person.FirstName);
            Assert.AreEqual(personFromDB.LastName, person.LastName);
        }








Una vez que sabemos que el test no funciona implementamos la funcionalidad.









        public void Save(T item)
        {
            if (!Table.Contains(item))
            {
                Table.InsertOnSubmit(item);
            }
            domainDataContext.SubmitChanges();
        }








Esto también nos muestra otro de los beneficios de TDD, y es la posibilidad de generar dise;os compactos, donde la funcionalidad es exclusivamente la necesaria para satisfacer el test.




Muestro la implementación del Find para tener una idea del uso extensivo de Linq en nuestra implementación.
















       public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> expression)
        {
            return GetAll()
                .Where(expression);
        }








UPDATE: se puede bajar el código desde NetIRepository









Lo que sigue









En el próximo post me voy a ocupar un poco de como utilizar el repositorio desde servicios y por medio de ellos en las distintas tecnologías de presentación.

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.