Novedades en C#7

Como es habitual, con la salida de una nueva versión de Visual Studio/.NET Framework en camino, tenemos también una nueva versión de uno de mis lenguajes de programación preferidos: C# 7.0.

En este post simplemente voy a nombrar las características principales que se vienen, pero para mayor detalle pueden ir al post What’s New in C# 7.0 del .NET Blog o bien ver el video News Features in C# 7.0 de Mads Torgersen – presentado recientemente para el evento Connect(); -.

¿Qué se trae esta nueva versión C#? Dejemos que ellos nos cuenten muy brevemente y luego pasamos a detallar algunas de las novedades principales:

C# 7.0 adds a number of new features and brings a focus on data consumption, code simplification and performance.

Tengan en cuenta que no estamos ante la versión final, por lo que alguna de las cosas que se comentan a continuación pueden sufrir cambios.

Sigue leyendo

Anuncios

Cascade-Lambda pattern

Es momento de hacer más interesante el patrón anterior. Antes que nada recordemos cual fue el resultado final en ese momento:

new EmailManager()
    .Client("client")
    .From("from@sebys.com.ar")
    .To("to@sebys.com.ar")
    .Subject("Envio email")
    .Body("Este es el contenido del e-mail")
    .Send();

Como podrán notar, el método Send() es el que realiza la “acción final” en todas las instancias de EmailManager. Esto nos permite deducir dos cosas, la primera es que toda instancia de EmailManager “finaliza” cuando realizamos el envío de correo y la segunda es que implícitamente estamos diciendo que para realizar un nuevo envío de correo necesitamos crear una nueva instancia. Aunque el comportamiento es bastante lógico, nuestra API no es explicitamente clara en su comportamiento.

Para hacer explicito este comportamiento, podemos hacer uso de las expresiones lambda.

Para trabajar con expresiones lambda vamos a convertir el método Send() es un método estático y cambiar su firma para que acepte un delegado Action<T>. Este delegado debe tomar como parámetro una instancia de EmailManager. Por último vamos a invocar la acción dentro del método, previo a realizar el envío propiamente dicho:

public static void Send(Action action)
{
    action(new EmailManager());
    Console.WriteLine("Enviar correo...");
}

Ahora veamos como cambia la forma de invocar a EmailManager:

static void Main(string[] args)
{
    EmailManager.Send((mail) => mail.Client("client")
                                   .From("from@sebys.com.ar")
                                   .To("to@sebys.com.ar")
                                   .Subject("Envio email")
                                   .Body("Este es el contenido"));
}

Con esto logramos eliminar toda confusión acerca de como debe realizarse el envió del e-mail, ya que lo que el método Send() establece claramente donde debe “construirse” el correo y que puede enviarse una única vez por instancia.

¡Espero que les sea de utilidad!

Abstract Factory Pattern

Después de una larga ausencia por motivos personales, vuelvo al ruedo. En esta oportunidad voy a escribir una sería de artículos volviendo a unos de los temas que más me interesan en programación que son los patrones de diseño. Para esta serie de post – y los ejemplos – me base en el artículo “Moving forward with .NET – Design Patterns” de la edición número 16 de la revista DNCMag.

Antes de arrancar con este patrón, veamos algunas definiciones (Wikipedia):

1. A factory creates objects.

2. The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.

La interpretación e implementación de este patrón puede ser variable. Una variación del mismo puede ser el patrón Factory, sin embargo si nos basamos en la definición anterior, este patrón lo que busca es que alguien se encargue crear instancias de objectos sin necesidad de especificar la clase concreta.

Veamos un ejemplo – aplicación de consola con C# – para que nos ayude a comprender mejor este patrón:

public class Book
{
    public string Title { get; set; }
   
    public int Pages { get; set; }
        
    public override string ToString()
    {
        return string.Format("Book {0} - {1}", Title, Pages);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(CreateInstance("AbstractFactoryPattern.Book", new Dictionary<string, object>() {
            {"Title", "Gulliver’s Travels"},
            {"Pages", 10},
        }));
    }

    private static object CreateInstance(string className, Dictionary<string, object> values)
    {
        Type type = Type.GetType(className);
        object instance = Activator.CreateInstance(type);

        foreach (var entry in values)
        {
            type.GetProperty(entry.Key).
            SetValue(instance, entry.
            Value, null);
        }
        return instance;
    }
}

En este sencillo ejemplo, la generación de instancias se delega al método CreateIntances(). Al momento de invocarlo hay que especificar como parámetros el nombre de la clase que queremos instanciar y los valores de sus propiedades por medio de un diccionario (key: nombre propiedad, value: valor).

Si bien pueden pensar que se trata solo de un método que crea instancias, este patrón puede ser muy poderoso cuando necesitamos generar nuevas instancias dinámicamente y en tiempo de ejecución a partir de las entrada de datos de un usuario. Además este patrón juega un papel clave en la inyección de dependencias (en el enlace hay mas detalle al respecto).

Si bien el ejemplo anterior es una demostración muy puntual de este patrón, existen otras formas de implementación como la del siguiente ejemplo.

Espero que les sea de utilidad!

Cascade Pattern

A cuantos de nosotros nos tocó alguna vez escribir código como el que vamos a ver a continuación?

public class EmailManager
{
    public string Client { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }

    public void Send()
    {
        // Enviar correo...
    }
}

Teniendo la clase EmailManager, la instanciación seria mas o menos de la siguiente forma:

var email = new EmailManager();
email.Client = "client";
email.From = "from@sebys.com.ar";
email.To = "to@sebys.com.ar";
email.Subject = "Envio email";
email.Body = "Este es el contenido del e-mail";

email.Send();

Si prestan atención al código notarán que hay algunas cositas que podríamos mejorar. En primer lugar, vemos que la variable “email” se repite un importante número de veces antes de realizar la acción final, esto nos lleva a pensar que tenemos código redundante que se puede evitar. Por otro lado no queda claro si para realizar un nuevo envío puedo utilizar la instancia ya creada o debería definir una nueva, lo que puede resultar confuso para cualquier desarrollador.

Para resolver esto hagamos algunas pequeñas adaptaciones al código:

public class EmailManager
{
    private string client { get; set; }
    private string from { get; set; }
    private string to { get; set; }
    private string subject { get; set; }
    private string body { get; set; }

    public EmailManager Client(string client)
    {
        this.client = client;
        return this;
    }

    public EmailManager From(string from)
    {
        this.from = from;
        return this;
    }

    public EmailManager To(string to)
    {
        this.to = to;
        return this;
    }

    public EmailManager Subject(string subject)
    {
        this.subject = subject;
        return this;
    }

    public EmailManager Body(string body)
    {
        this.body = body;
        return this;
    }

    public void Send()
    {
        // Enviar correo...
    }
}

Lo que hicimos es agregar a cada propiedad un método que devuelve la instancia del objeto creado, lo que nos permite ir invocando nuevos métodos sin necesidad de escribir una nueva línea.

Veamos como es la nueva forma de instanciarlo:

new EmailManager()
    .Client("client")
    .From("from@sebys.com.ar")
    .To("to@sebys.com.ar")
    .Subject("Envio email")
    .Body("Este es el contenido del e-mail")
    .Send();

Como resultado, se logra eliminar código duplicado logrando más legibilidad y simplicidad de uso.

Algunos frameworks que nos ayudan con esta tarea son FluentValidation y NBuilder. Por último, un patrón alternativo y del que ya habíamos hablado en el post es Fluent Interface.

Espero que les sea de utilidad!

Patrón PRG

En esta oportunidad vamos a hablar del patrón PRG (Post-Redirect-Get) el cual es aplicable en el desarrollo web. Tal como el nombre nos sugiere, lo que se logra con esta técnica es que la respuesta a una petición POST sea una re-dirección que nos permita obtener una nueva página por medio de una petición GET.

Antes que nada veamos, utilizando un escenario bastante común en los sitios web, el problema de no aplicar este patrón. Imaginemos un formulario de contacto, en donde el usuario carga información y se envía a un servidor web que la recibe y procesa. Por último informamos al usuario que la operación se realizó con éxito por medio de una nueva página.

En este último punto es donde arriba el problema, ya que si el usuario por esas cosas de la vida se le ocurre actualizar esta última página (F5) aparecerá el siguiente cuadro de dialogo:

Dialogo

Dialogo

El primer problema con esta advertencia es que el usuario posiblemente no entienda el mensaje (en el cual se pregunta si quiere volver a enviar la información del formulario). Por este motivo posiblemente intente reenviar la información cuando ya lo hizo!.

En el caso de hacerlo (botón “Reintentar”) se volverá a realizar la petición POST y nuevamente estaremos procesando la lógica del formulario de contacto (o el formulario que corresponda). Esto, entre otros problemas, nos puede generar registros duplicados, notificaciones duplicadas, etc …  :/

Para prevenir estos casos lo que PRG nos sugiere es lo siguiente:

  1. Recibimos una petición POST con los datos del formulario y ejecutamos la lógica que corresponda.
  2. Respondemos al cliente con una redirección (código de estados HTTP 30x) para que el navegador sepa que debe solicitar otra página (en el ejemplo sería la pantalla que informa que los datos de contacto se enviaron correctamente).
  3. El navegador obtiene esta página mediante una petición GET.

Vista la teoría, vamos a la práctica.

Aclaración: en el siguiente ejemplo voy aplicar el patrón PRG en una aplicación ASP.NET MVC pero es totalmente posible hacerlo en cualquier otra tecnología web (WebForms, PHP…).

Siguiendo el ejemplo de arriba, nuestro método de acción debería quedar  mas o menos así:

Aplicando el patrón PRG

Aplicando el patrón PRG

Muy simple, no?! En un post anterior vimos lo facil que es hacer re-direcciones en ASP.NET MVC. Veamos la respuesta del servidor luego de procesar la petición POST:

Respuesta del servidor

Respuesta del servidor

En primer lugar la respuesta a la petición POST es una re-dirección (HTTP Status 302). En segundo lugar se solicita la página “de agradecimiento” por medio de una petición GET, la cual es devuelta con éxito (HTTP Status 200). Si ahora al usuario se le ocurriera actualizar la página, el navegador le retornará la última petición realizada (petición GET).

Como pueden ver, aplicar esta patrón es muy simple, aún más con ASP.NET MVC (solo basta con modificar la respuesta en nuestro método de acción).

Espero que les sea de utilidad 🙂

Integrando NUnit a Visual Studio 2012

NUnit

NUnit

Ya hemos hablado en post anteriores acerca de NUnit (para quienes no lo conozcan, es un framework open source para test unitarios escritos en C#). En esta oportunidad quiero contarles como integrar esta herramienta a Visual Studio 2012.

En primer lugar van a agregar la referencia a la librería NUnit al proyecto de test. Pueden hacerlo desde la consola con el siguiente comando (TOOLS\Library Package Manager\Package Manager Console\):

PM> Install-Package NUnit

En segundo lugar vamos a crear un simple unit test con NUnit:

Creando un simple test con Nunit.

Creando un simple test con Nunit.

Es momento de instalar la extensión para VS 2012. Para esto abrimos la ventana de Extensions and Updates (TOOLS\Extensions and Updates…\), seleccionamos la pestaña Online y realizamos una búsqueda por nunit:

Extensions and Updates

Extensions and Updates

Seleccionamos la extensión NUnit Test Adapter (Beta 4) y la descargamos. Finalizada esta operación nos pedirá que reiniciemos VS 2012.

Una vez que levante VS, simplemente corremos el test y ya podremos visualizar el resultado en la pestaña “Test Explorer”:

Test Explorer

Test Explorer

Espero que les sea de utilidad.

DIP – Principio de Inversión de Dependencias

Un post que tenía pendiente hace mucho tiempo era acerca del quinto principio SOLID llamado Principio de Inversión de Dependencias (Dependency Inversion Principle). Este principio nos dice que “dependamos de abstracciones, no de concreciones”. Tío Bob plantea dos puntos en la definición de este principio:

A. Las clases de alto nivel no deberían depender de las clases de bajo nivel. Ambas deberían depender de las abstracciones. B. Las abstracciones no deberían depender de los detalles. Los detalles deberían depender de las abstracciones.

Este principio, en conjunto con el resto de los principio SOLID, están orientados a reducir problemas relacionados con el mal diseño (aún cuando tengamos el código bien organizado en clases). Tio Bob  dice que en todo mal diseñose presentan alguna de las siguientes características:

  • Rigidez: un cambio afecta a muchas partes de un sistema.
  • Fragilidad: cada cambio genere problemas en lugares inesperados.
  • Inmovilidad: imposible de reusar.

Una forma muy simple de detectar un mal diseño es cuando tenemos “miedo” de tocar el código, porque creemos que en alguna parte algo se va a romper. Veamos un ejemplo de código mal diseñado y como podemos mejorarlo aplicando los principios SOLID, sobre todo DIP. Continuando con el mismo tema de los últimos post de la serie, supongamos que tenemos la clase PrecesoAutorizacionTarea que contiene el método Iniciar(). Este método se encarga, entre otras cosas, de loggearinformación acerca del inicio del proceso y el plazo máximo de aprobación de la tarea:

Definición clase ProcesoAutorizacionTarea

Definición clase ProcesoAutorizacionTarea

Es fácil detectar varios “errores” de diseño en la implementación del método. El primero de ellos es que es un diseño rígido. Supongamos que tenemos que agregar una nueva propiedad a la clase TxtLog para especificar el path o file del archivo de log a utilizar? Esta claro que deberíamos cambiar todas las instancias de TxtLog en el código, salvo que quisiéramos registrar “todo” en el archivo de log especificado por default (pero en tal caso, no tendría sentido dicha propiedad).

Para resolverlo, supongamos que decido especificar esta propiedad “a mano” (logger.Path = “…”;) en todas las porciones de código que sean necesarias (es decir, donde no me sea útil el archivo por default). En tal caso nos encontrarímos con un diseño frágil, ya que si nos olvidamos de especificarlo, estaríamos registrando información en un archivo de log, que sería el incorrecto. Algo similar ocurre con el calculo del plazo máximo de autorización de la Tarea… qué pasa si necesito realizar el mismo cálculo en otro módulo? O qué pasa si ahora tengo un nuevo tipo de tarea? Es realmente responsabilidad de la clase ProcesoAutorizacionTarea realizar dicho cálculo?… esta claro que las respuestas a estas preguntan nos conducen ante un mal diseño. Bien, para poder solucionar estos problemas, vamos a realizar una serie de cambios, el primero respecto al lugar donde se instancia el objeto TxtLog:

Resolviendo problemas de rigidez y fragilidad

Resolviendo problemas de rigidez y fragilidad

Como podemos ver, ahora la instancia de TxtLog la recibe el constructor de la clase ProcesoAutorizacionTarea, por lo que cada cambio que tengamos que realizar sobre dicha instancia, podemos hacerlo en un único lugar. Notemos que en este caso estamos “inyectando” al objeto ProcesoAutorizacionTarea  un objeto TxtLog, es decir su dependencia. Esto se denomina Inyección de Dependencias y sobre este tema hemos hablado en varios post. Bien, resuelto esto, tenemos otro problema, seguimos teniendo un mal diseño, ya que es inmóvil. Supongamos que el día de mañana, se desea utilizar un DbLog o XmlLog. Este cambio podría ser un dolor de cabeza, ya que el proceso depende exclusivamente de TxtLog. Algo similar ocurre si necesitamos realizar el calculo de un proceso “SEMI-AUTOMATICO”? Entonces veamos como corregir este error de diseño. Antes que nada vamos a generar las interfaces ILog e ICalculadorPlazosTarea – esta última es una pobre traducción que se me ocurrió, reconozco que con el tiempo se me hizo complicado definir nombres en español 🙂 -.

Definiendo las interfaces

Definiendo las interfaces

Lo siguiente, generar las clases que lo implementen. Por un lado tendremos TxtLog que implementa ILog y por el otro dos nuevas clases llamadas CalculadorPlazosTareaX CalculadorPlazosTareaY que implementan ICalculadorPlazosTarea. Comencemos con TxtLog:

Redefiniendo TxtLog

Redefiniendo TxtLog

Ahora las nuevas clases “calculadoras de plazos”:

Implementaciones de ICalculadorPlazosTarea

Implementaciones de ICalculadorPlazosTarea

Bien, por último solo resta eliminar las dependencias (o mejor dicho invertirlas) de la clase ProcesoAutorizacionTarea:

Aplicando DIP a la clase ProcesoAutorizacionTarea

Aplicando DIP a la clase ProcesoAutorizacionTarea

Como podemos ver  el punto A del principio estaría resuelto con la intrdocción de ILog, ya que ahora tanto ProcesoAutorizacionTarea como TxtLog dependen de una abstracción (es decir, de ILog). También estaríamos cumpliendo del punto B, ya que por ejemplo, los métodos para calcular plazos dependen de la abstracción ICalculadorPlazosTarea y no de la clase ProcesoAutorizacionTarea. Espero que les sea de utilidad!