YoProgramo.NET Blog
Anotaciones de Programador

Dynamic C#4

Microsoft acababa de lanzar Visual Studio 2010. Con él se vienen, nuevos e importantes cambios. Algunos cambios incluidos en el nuevo Framework .NET 4.0 están modificando el paradigma para los programadores.

De las nuevas características, la más llamativa sin lugar a dudas se halla en el  factor dinámico. Microsoft incluyó al framework un nuevo tipo denominado “dynamic”, buscando aliviar el trabajo de los programadores.

Con la programación dinámica muchas de las cosas que anteriormente se realizaban en tiempo de compilación, se podrán hacer en tiempo de ejecución. Esto puede ser muy práctico para escribir código, dado que no necesitaremos programar basados en tipos de objetos, sino más bien basándonos en el comportamiento de los mismos.

Sólo mira el siguiente código y podrás entender en qué consiste dynamic.

dynamic e = 1;
e.Prueba();

int w = e + 2;

Console.Write(e);
Console.Write(w);

En la línea 1, creamos un objeto dynamic. En la siguiente línea, llamamos a un método Prueba(), el cual el compilador lo pasará por alto. De este modo, aunque te parezca extraño, este código compila sin errores. Pero cuando ejecutemos la aplicación, lanzará una excepción en tiempo de ejecución, porque el tipo Int no expone un método llamado “Prueba”.

Por eso es importante diferenciar las cosas que se realizan en tiempo de compilación y cuales en tiempo de ejecución. Los objetos dynamic tienen una particularidad, todas sus propiedades y comportamientos se resolverán en tiempo de ejecución.

Lo malo de la programación dinámica:

Todas las ventajas que observamos en la programación dinámica pueden ser favorables, aunque también tiene su lado negativo.  Una aplicación que lance excepciones en tiempo de ejecución arroja un grado de incertidumbre para el comportamiento de la misma. También debemos olvidarnos de algunas características de los lenguajes estáticos como por ejemplo: Herramientas Intellisense, performance y el escalamiento de las aplicaciones.

DLR

Para que la programación dinámica sea posible, Microsoft incorporó una importante capa más sobre el CLR, a la que llamó DLR.

El DLR está encargado del enlace dinámico y de suministrar un medio o soporte común para la comunicación entre distintos lenguajes como C#, VB, IronPyton, IronRuby, etc.

Es un complemento al CLR y por lo tanto no lo suplanta.  El DLR se trata de un set o conjuntos de dlls, librerías, etc. que se ubican sobre el CLR, haciendo de puente entre los lenguajes dinámicos y proporcionando un marco en tiempo de ejecución para los lenguajes y un punto de enlace entre lenguajes estáticos y no estáticos.

June 25, 2010 03:52 by fabianfigueredo
Categorías: C#

Manejo de Especificaciones con el delegado Func

Al leer el post de Darío llamado “Predicados y Especificaciones” y luego de hablar ayer con José quise implementar lo que Darío escribió en ese post usando lo que me enseño José. La idea es utilizar el delegado Func<T, bool> en vez de un delegado común.

En el código fuente de yoprogramo.net existen muchas partes donde necesito especificar cosas, ya sea para consultas, etc. Para esto el patrón de especificaciones anda perfecto, les muestro lo que yo hice.

Mi función antes de usar especificaciones:

public IList<IPost> TraerPostsParaHome(int? top)
{
    var query = (from s in TraerTodosSinSpam()
                 where !s.Bloqueado
                 orderby s.PostedAt descending
                 select s).Take(top ?? 100).ToList();
}

Y ahora, luego del refactory quedó así:

public IList<IPost> TraerPostsParaHome(int? top)
{
    return TraerTodosSinSpam()
            .Where(PostEspecificacion.EsApto)
            .OrderByDescending(PostEspecificacion.OrdenarHomePor)
            .Take(top ?? 100)
            .ToList();
}

Mi clase PostEspecificacion:

namespace YoProgramo.Core.Especificaciones
{
    public class PostEspecificacion
    {
        public static Func<IPost, bool> EsApto
        {
            get
            {
                return x => !x.Bloqueado;
            }            
        }

        public static Func<IPost, DateTime> OrdenarHomePor
        {
            get
            {
                return x => x.PostedAt;
            }
        }
    }
}
December 23, 2009 11:35 by fabianfigueredo
Categorías: C#

DDD: Controladores gordos

FatLos controladores son una parte vital de nuestra aplicación, en ellos ocurren procesos importantes del lado del servidor y muchas veces los controladores culminan albergando muchas líneas de código.

Tener controladores gordos no está muy bien que digamos. Particularmente, cuando programo controladores no me gusta llamar a Repositorios, prefiero utilizar instancias de servicios.

Para despejarme estas dudas pregunté esto en la comunidad AltnetHispano y muy gentilmente los muchachos me contestaron.

¿Porque los controladores suben de peso?

  • Al usar directamente Repositorios en nuestros Controladores es probable que terminemos incluyendo Lógica de Negocio en ellos.
  • Hacer reiterativas llamadas a servicios también es malo. En general, si esto es necesario es probable que necesites replantearte donde deberían ir esas líneas de código.

DDD 

Recordemos, que en arquitecturas DDD, los repositorios pertenecen al Dominio pero en realidad son implementados o inyectados en la capa de infraestructura.
En la capa de servicios de aplicación, solo existen interfaces de servicios que luego son inyectados por algún IoC a los servicios con comportamiento.
Un controlador debería poder acceder al dominio para tener acceso a las interfaces de las entidades.

Conclusión:

Usar servicios de aplicación y que estos sean los encargados de acceder a los repositorios es definitivamente una buena idea.
Y recordemos siempre, los controladores deben ser lo más pequeños posibles y fáciles de entender.

Más información: The Fat Controller must die!

December 22, 2009 07:56 by fabianfigueredo
Categorías: C# | Arquitectura | ASP.NET

“SELECT NOT IN” en Linq

Para los que quieran hacer un “not in” en Linq es muy fácil, solo hay que usar el operador ! en el clausula Where. Aquí publico el método TraerTodosSinSpam() del servicio PostServicio de la nueva versión de este portal:

public IList<IPost> TraerTodosSinSpam()
{
    var spamsReportados = 
        _spamReportadoServicio.TraerTodasLasEntidades();

    var query = (from c in _postRepositorio.TraerTodos()
                where !(from o in spamsReportados
                        select o.Id).Contains(c.Id)
                 select c).ToList<IPost>();

    return query;            
}
December 11, 2009 07:37 by fabianfigueredo
Categorías: C#

TDD Falsos Repositorios para Servicios

Ayer, Mario y Ángel me señalaron algunos errores en mi post anterior, en realidad es posible evitar tener que escribir la clase FalsoPostRepositorio.

Aquí les muestro como quedo mi test Crear_post_Test() donde utilizo Callback de moq.

        [TestMethod()]
        public void Crear_post_Test()
        {
            Dictionary<long, IPost> posts = new Dictionary<long, IPost>();
            var falso_repositorio = new Mock<IPostRepositorio>();
            falso_repositorio
                .Setup(x => x.Agregar(It.IsAny<IPost>()))
                .Callback((IPost p) => posts.Add(p.Id, p));
            
            IPostServicio servicioPost = new PostServicio(falso_repositorio.Object);
            IPost post = new Post();
            post.Id = 1;
            post.Title = "Prueba";

            servicioPost.Crear(post);

            Assert.AreEqual(posts.Count, 1);
            Assert.AreEqual(posts[1], post);
        }

y el test que prueba la actualización seria el siguiente:

        [TestMethod()]
        public void Actualizar_post()
        {
            Dictionary<long, IPost> posts = new Dictionary<long, IPost>();
            IPost post = new Post();
            post.Id = 1;
            post.Title = "Prueba";
            posts.Add(1, post);
            var falso_repositorio = new Mock<IPostRepositorio>();
                falso_repositorio
                    .Setup(x => x.Actualizar(IsAny<IPost>()))
                    .Callback<IPost>((p) => posts.ActualizarPost(p));

            IPostServicio servicioPost = new PostServicio(falso_repositorio.Object);
            post = new Post();
            post.Id = 1;
            post.Title = "Prueba actualizada";

            servicioPost.Actualizar(post);

            Assert.AreEqual(posts[1].Title, "Prueba actualizada");
        }

ActualizarPost() es un método de extensión.

December 3, 2009 08:10 by fabianfigueredo
Categorías: C# | TDD

TDD diseñando Servicios y Repositorios

obreros

Estoy en medio de una *BIG REFACTORY* del código fuente de yoprogramo.net, pero el motivo de este post no es contarles eso si no comentarles como estoy realizando mis tests para diseñar Servicios y Repositorios.

Lo primero, tenemos que tener algo en claro, para programar bien #TDD es necesario conocer algunas cosas, que ya ayer Carlos Peix explico muy bien en su WebCast. Para que nuestra capa de servicios sea optima para TDD es necesario que apliquemos el patrón Inyección de Dependencias y que utilicemos algún contenedor IoC para trabajar con ellas.

Si no tienes conocimientos de estas herramientas y patrones te invito a que veas mi video tutorial sobre contenedores IoC.

Usare como ejemplo, algo del mundo real –copiándole a José- que aplique en yoprogramo.net para diseñar mis servicios.

Diseñando el servicio IPostServicio:

Este servicio estará en la capa infraestructura de la aplicación:

namespace YoProgramo.Nucleo
{
    public interface IPostServicio {
        IList TraerTodos();
        IList TraerTodosSinSpam();
        IList TraerPostsParaHome(int? top);
        IPost TraerPorId(long id);
        IList TraerPorTag(ITag tag);
        IList TraerPorUsuario(IUser usuario);
        IList TraerFavoritosPorUsuario(IUser usuario);
        IList TraerTodosLosPostsSinRespuestas();
        IList GetByCategory(ICategoria categoria);
        IPost TraerPorSlug(string slug);
        void Crear(IPost obj);
        void Actualizar(IPost obj);
        void Borrar(IPost obj);
    }
}

Luego de crear la interface, empecé con el diseño y creación de los tests. El primero que les mostraré es uno para probar el método TraerTodos(). Es necesario utilizar alguna librería de mock *yo utilizo moq* para poder mockear el repositorio que utiliza el servicio.

Se dice que estos tests son de diseño, porque en realidad la clase PostServicio no existe y luego de crear el test iremos refactorizando hasta lograr tener terminada la clase con todos sus métodos funcionando.

namespace YoProgramo.Infraestructura.Tests
{
    [TestClass()]
    public class PostServicioTest
    {
        public IList HacerListaDePosts()
        {
            var lista = new List();
            IPost post = new Post();
            lista.Add(post);
            post = new Post();
            lista.Add(post);
            return lista;
        }

        [TestMethod()]
        public void Traer_todos_y_comprobar_que_no_sea_nulo_y_que_sean_2()
        {
            var falso_repositorio = new Mock();
            falso_repositorio
                .Setup(x => x.TraerTodos()).Returns(HacerListaDePosts());
            IPostServicio servicioPost = new PostServicio(falso_repositorio.Object);

            var list_de_posts = servicioPost.TraerTodos();

            Assert.IsNotNull(list_de_posts);
            Assert.AreEqual(list_de_posts.Count(), 2);            
        }
    }
}

Primero creamos un mock – un mock es un objeto proxy – para así luego modificar su comportamiento, en este caso indicamos que al llamar al método TraerTodos() retorne una lista de objetos Post. Luego este objeto mock lo utilizamos para enviarlo al servicio a través de su constructor.

Refactoring, refactoring…

Al terminar el test el mismo falla y aquí es donde comienza el trabajo verdadero en TDD, hay que refactorizar para lograr superar nuestras pruebas.

Mi clase PostServicio luego del refactoreo:

namespace YoProgramo.Infraestructura.Servicios
{
    public class PostServicio : IPostServicio
    {
        protected IPostRepositorio _postRepositorio;

        public PostServicio(IPostRepositorio postRepositorio)
        {
            _postRepositorio = postRepositorio;
        }

        #region IPostServicio Members

        public IList TraerTodos()
        {
            return this._postRepositorio.TraerTodos();
        }

        public IList TraerTodosSinSpam()
        {
            throw new NotImplementedException();
        }

        public IList TraerPostsParaHome(int? top)
        {
            throw new NotImplementedException();
        }

        public IList TraerPorTag(ITag tag)
        {
            throw new NotImplementedException();
        }

        public IList TraerPorUsuario(IUser user)
        {
            throw new NotImplementedException();
        }

        public IList TraerFavoritosPorUsuario(IUser user)
        {
            throw new NotImplementedException();
        }

        public IList TraerTodosLosPostsSinRespuestas()
        {
            throw new NotImplementedException();
        }

        public IList GetByCategory(ICategoria categoria)
        {
            throw new NotImplementedException();
        }

        public IPost TraerPorSlug(string slug)
        {
            throw new NotImplementedException();
        }

        public void Crear(IPost obj)
        {
            _postRepositorio.Agregar(obj);            
        }

        public void Actualizar(IPost obj)
        {
            _postRepositorio.Actualizar(obj);            
        }

        public void Borrar(IPost obj)
        {
            _postRepositorio.Borrar(obj);  
        }

        public IPost TraerPorId(long id)
        {
            return _postRepositorio.Get(id);
        }

        #endregion
    }
}

Solo implemente los métodos que utilizo para estas pruebas especificas, los demás serán para otros tests.

Falsos repositorios:

No siempre podemos mockear, en ocasiones tendremos que diseñar falsos objetos a pata, lo feo de esto es que este código es solo para las pruebas, no se usa en otra parte. Puede hacernos perder tiempo pero es necesario para que nuestras pruebas sean óptimas. Ahora veamos este test…

        [TestMethod()]
        public void Actualizar_post()
        {
            var falso_repositorio = new FalsoPostRepositorio();
            IPostServicio servicioPost = new PostServicio(falso_repositorio);
            IPost post = new Post();
            post.Id = 1;
            post.Title = "Prueba";

            servicioPost.Crear(post);
            IPost postParaActualizar = servicioPost.TraerPorId(1);
            postParaActualizar.Title = "Prueba actualizada";
            servicioPost.Actualizar(postParaActualizar);

            IPost postEsperado = servicioPost.TraerPorId(1);

            Assert.IsNotNull(postEsperado);
            Assert.AreEqual(postEsperado.Title, "Prueba actualizada");
        }

Como ven, aquí no utilizo mock dado que para actualizar objetos necesitamos algo de interacción con el repositorio, de hecho estamos realizando dos pasos, uno para crear un objeto y otro para modificarlo.

Mi Falso Repositorio:

namespace YoProgramo.Infraestructura.Tests.FalsosRepositorios
{
    public class FalsoPostRepositorio : IPostRepositorio
    {
        private Dictionary<long, IPost> posts;

        public FalsoPostRepositorio()
        {
            posts = new Dictionary<long, IPost>;
        }


        #region IRepositorio Members

        public IPost Get(long id)
        {
            return posts[id];
        }

        public IList TraerTodos()
        {
            throw new NotImplementedException();
        }

        public void Borrar(IPost entidad)
        {
            posts.Remove(entidad.Id);
        }

        public void Agregar(IPost entidad)
        {
            posts.Add(entidad.Id ,entidad);
        }

        public void Actualizar(IPost entidad)
        {
            posts[entidad.Id] = entidad;
        }

        public IList FindAll()
        {
            throw new NotImplementedException();
        }

        public IList FindAll(System.Linq.Expressions.Expression> expression)
        {
            throw new NotImplementedException();
        }

        public IQueryable Find()
        {
            throw new NotImplementedException();
        }

        public IQueryable Find(long id)
        {
            throw new NotImplementedException();
        }

        public IQueryable Find(System.Linq.Expressions.Expression> expression)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

Y esto es todo por hoy, nada más que decir sobre el tema. Con el webcast de ayer me entusiasme mas con esto y ahora ya es tarde para escaparme jeje.

December 2, 2009 08:45 by fabianfigueredo
Categorías: C# | TDD

Como hacer interfaces fluidas en C#

Todo framework importante o conocido las usa, son las interfaces que exponen métodos que fluyen logrando que nuestro trabajo pueda ser un poco más sencillo.

Una interface fluida (Fluent Api) es una interface o conjunto de ellas que exponen métodos que concatenados forman frases o simplemente verbos, de esta manera se obtiene un código fácil de leer y comprender por los programadores.

Como hacer interfaces fluentes en C#

Ejemplo de Interface fluida:

Como dije, necesitaremos crear una interface con los métodos que necesitamos, como se ve aquí:

    public interface IFooFluent : IOcultarMiembros
    {
        IFooFluent Palabra(string palabra);
        IFooFluent Recortar(int length);
        IFooFluent PasarMayusculas();
        IFooFluent PasarMinusculas();
        string DameString();
    }

Vemos que la interface IFooFluent hereda IOcultarMiembros que es la encargada de ocultar los métodos que expone System.Object (GetType, GetHasCode, ToStgring, Equals)

    [EditorBrowsable(EditorBrowsableState.Never)]
    public interface IOcultarMiembros
    {
        [EditorBrowsable(EditorBrowsableState.Never)]
        Type GetType();

        [EditorBrowsable(EditorBrowsableState.Never)]
        int GetHashCode();

        [EditorBrowsable(EditorBrowsableState.Never)]
        string ToString();

        [EditorBrowsable(EditorBrowsableState.Never)]
        bool Equals(object obj);
    }

Y las clases Foo y Fluente:

    public class Foo : IFooFluent
    {
        private string _palabra;

        public IFooFluent Palabra(string palabra)
        {
            _palabra = palabra;
            return this;
        }


        public IFooFluent Recortar(int length)
        {
            _palabra = _palabra.Substring(0, length);
            return this;
        }

        public IFooFluent PasarMayusculas()
        {
            _palabra = _palabra.ToUpper();
            return this;
        }

        public IFooFluent PasarMinusculas()
        {
            _palabra = _palabra.ToLower();
            return this;
        }

        public string DameString()
        {
            return _palabra;
        }
    }

    public class Fluente : IOcultarMiembros
    {
        public static IFooFluent Hacer()
        {
           return new Foo();
        }
    }

El resultado:

Fluente

Puntos a tener en cuenta al crear una interface fluent:

  • La propiedad EditorBrowsable no funciona si la interface se encuentra en el mismo assembly. Deberán hacer dos proyectos, uno para las librerías donde estará la interface fluente y en el otro hacer referencia a este por medio de la DLL, (No hacer referencia por proyecto).
  • Si utilizas Resharper es posible que no funcione EditorBrowsable.

Más sobre interfaces fluidas:

November 13, 2009 09:35 by fabianfigueredo
Categorías: C#

Struct vs Clases – ¿Cuales son las diferencias?

Si observamos la sintaxis, struct y clases en C# son casi idénticas. ¿Pero cual es la diferencia entre estos?

Struct:

  • Es un Value Type
  • Se almacena en Stack Memory.
  • Es un tipo compuesto o conjunto de una serie de otros tipos.
  • No pueden tener constructores explícitos sin parámetros.
  • No pueden tener destructores.
  • No pueden implementar herencias.
  • Mas rápidas y no necesitan del Garbage Collector.
  • Dentro del framework .NET hay muchos Struct como por ejemplo System.Int32, System.Single, etc.
  • Cuando es pasado por parámetro de método, es pasado “por valor”

Clase:

  • Es Reference Type.
  • Se almacena en “heap”.
  • Soporta herencias.
  • Para instanciar es necesario usar el operador “new”.
  • Cuando es pasado por parámetro de método, es pasado “por referencia”.
November 8, 2009 08:56 by fabianfigueredo
Categorías: C#

Salió NH2.1.1GA

Fabio Maulo anunció hoy que se liberó la última versión de NHIbernate.
A descargar muchachos!

http://sourceforge.net/projects/nhibernate/

October 31, 2009 10:10 by fabianfigueredo
Categorías: C#

Errores,Try, Catch y las buenas prácticas

Ayer hablaba con Darío Quintana sobre buenas prácticas de programación y me gustaría comentarlo aquí con ustedes. Darío me señaló un error que vio en un código que publiqué por twitter, en ese código el autor utilizaba  try{} catch{} de forma incorrecta.

¿Como se debe utilizar Try{} Catch{}?

Siempre digo, –y no es nada nuevo- “utiliza Try{} Catch{} solo para manejar errores y nada más”. Pero la verdad es que nosotros los programadores solemos utilizarlos de mala manera, cambiando su real finalidad.

Ejemplo 1: Uso incorrecto de Try{} Catch{}

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int numero;

            try
            {
                numero = Multiplicar("999999999999", "9999999999999");
            }
            catch
            {
                numero = 0;
            }
            finally            
            {
                Console.Write("Operación finalizada..");
                Console.WriteLine();
            }

            Console.Write(numero);
            Console.ReadKey();
        }

        public static int Multiplicar (string a, string b)
        {
            int a1 = int.Parse(a);
            int b1 = int.Parse(b);
            return a1 * b1;
        }
    }
}

Aquí vemos algunas cosas mal, en la porción “Catch” estamos insertando lógica importante, esto no esta bien. En los Catchs solo hay que manejar excepciones y nada mas.

En este caso, se lanzará una excepción en la primera línea de la función Multiplicar. Pero en realidad las tres líneas de código de esta función son susceptibles a que ocurra una excepción no controlada.

Ejemplo 2: Uso correcto de Try{} Catch{}.

static void Main(string[] args)
{
    int numero = 0;

    try
    {
        numero = Multiplicar("999999999999", "9999999999999");
    }
    catch
    {
	//Ha ocurrido un error y aquí podemos realizar varias cosas,
        //pero todas relacionadas a la excepción, 
        //por ejemplo escribir algún log, 
        //lanzar excepciones de algún tipo en especial, etc.
        throw;
    }
    finally
    {
        Console.Write("Operación finalizada..");
    }

    Console.WriteLine();
    Console.Write(numero);
    Console.ReadKey();
}

Quitamos la pequeña línea de código del catch y solo dejamos líneas relacionadas al manejo de la excepción.

NO uses porciones Catch para:

  • “Seguir la aplicación sea o sea” Muchas veces solemos hacer esto, utilizamos try/catch para garantizarnos que la aplicación continúe funcionando aunque hayan errores. La finalidad de try/catch es manejar excepciones, lo mejor siempre será lanzar las excepciones.
  • Retornar valores de un método o función.
  • Limpieza de objetos: en realidad para ello deberías utilizar la porción Finaly
  • Insertar lógica: Definitivamente esto esta muy mal. Recuerda, solo inserta líneas de código para manejar la excepción.
October 28, 2009 21:11 by fabianfigueredo
Categorías: C#