jueves, abril 15, 2010

Introducción a MEF Parte 2

Siguiendo con el ejemplo del post anterior sobre MEF (La aplicación para consola “Saludador” que presente en el Launch de Visual Studio 2010 en Tijuana). En este screencast muestro como usar MEF para que alguien que no tiene acceso al código fuente de la aplicación, pueda extenderla (plugins) y agregar sus propios saludos.

Debido a que los videos solo los quiero realizar de 5 min, tuve que irme (quizás) un poco rápido. Como siempre cualquier comentario es bienvenido.

Post relacionado: Introducción a MEF Parte 1

Código Fuente:

martes, abril 13, 2010

Introducción a MEF Parte 1

En el pasado Launch de Visual Studio 2010 en Tijuana presenté el tema: Extendiendo Aplicaciones con MEF. Debido a que olvide grabar la presentación, quise rehacer el ejemplo dividiéndolo en screencasts de no mas 5 min. Usando el mismo ejemplo que en la sesión. Espero sirva como introducción para quienes quieran conocer sobre MEF (Managed Extensibility Framework).

El ejemplo trata de una aplicación para consola que tiene una lista de saludos, el usuario puede seleccionar el saludo que guste y ejecutarlo. La idea es que el saludador pueda ser extendido, de tal forma que yo (como desarrollador de la aplicación) o cualquier tercero pueda agregar saludos a la aplicación.

En este primer video, muestro el funcionamiento básico de MEF (Importar, Exportar y Componer).

Post Relacionado: Introducción a MEF Parte 2

martes, marzo 30, 2010

Singleton con Unity

En la pasada reunión de la comunidad TJ.Net presenté el tema IoC, donde mostré un ejemplo usando el contenedor de dependencias Unity. Una de las preguntas de los asistentes fue sobre si unity siempre crea nuevas instancias para los tipos registrados y como podría indicarle que utilice siempre la misma (lo que se conoce como el patrón singleton). Al momento de la reunión conteste que por omisión Unity crea una nueva instancia cada que resuelve un tipo, pero que sí era posible indicar un comportamiento distinto, sin embargo no recordé la manera exacta para ello. Bueno pues aquí la respuesta.

Al registrar un tipo con el método registerType<TFrom, TTo> podemos pasarle un LifetimeManager el cual será encargado de manejar el tiempo de vida de las instancias resueltas por el contenedor. Podríamos crear nuestro propio LifetimeManager, pero (para el caso del patrón singleton) unity ya cuenta con uno del tipo ContainerControlledLifetimeManager.

Así que lo único que necesitamos para que nuestro contenedor implemente el patrón singleton al momento de resolver nuestro tipo es pasarle una instancia de la clase ContainerControlledLifetimeManager. Utilizando el mismo ejemplo de la reunión, podríamos suponer que necesitamos que nuestro INotificationService sea siempre la misma instancia para todos los componentes que requieran usarlo. Entonces el código donde registramos nuestro tipo quedaría así:

container.RegisterType<INotificationService, NotificationServiceWithTemplates>(
new
ContainerControlledLifetimeManager());
Con esto logramos el patrón singleton con unity.

jueves, marzo 25, 2010

Inversión de Control - IoC

El día de ayer (Miércoles 24 de Marzo 2010) fue la Reunión 33 de la comunidad TJ.NET donde presenté el tema “Inversión de control (IoC)”. La reunión se llevo a cabo en las instalaciones del Instituto Tecnológico de Tijuana.

En la reunión presenté una introducción a lo que se refiere el principio IoC; con ejemplos como: el usar eventos en nuestros componentes para la interfaz de usuario y el utilizar un Contenedor de dependencias (IoC Container) para realizar una Inversión de control aplicando el patrón de diseño “Inyección de dependencias”. Como ejemplo se refactorizó una aplicación Web ASP.NET para usar un IoC Container (Unity en este caso). La presentación que fue grabada y el material (diapositivas y archivos) pueden ser descargados desde la página del evento en la comunidad.



Fotos

 


Presentación y archivos

 

jueves, febrero 11, 2010

Iniciando con MongoDB desde .Net

En el post anterior mostré como iniciar con mongoDB utilizando las herramientas que obtenemos al descargar la base de datos. Ahora quiero mostrar las mismas operaciones pero desde .Net (específicamente C#). Para esto es necesario descargar el driver para hablar con mongo desde .net

Para abrir la conexión a la base de datos debo crear una instancia de la clase MongoDB.Driver.Mongo, llamar el método Connect y después hacer un getDB con el nombre de la base de datos a la que quiero conectarme. Tomando el ejemplo anterior de la libreta de direcciones, el código queda así:

var mongo = new Mongo();
mongo.Connect();
var db = mongo.getDB("AddressBook");

una vez conectado a la base de datos obtengo una referencia a mi colección de documentos llamada “Contacts” (similar al concepto de tabla en una base de datos relacional).

var contacts = db.GetCollection("Contacts");

Ahora para insertar documentos creamos instancias de la clase MongoDB.Driver.Document (el cual es básicamente un diccionario de datos), le damos valores y lo insertamos a nuestra colección de contactos; como en el post anterior inserto 2 documentos a nuestra colección:

var mario = new Document();
mario["Name"] = "Mario";
mario["Phone"] = "1234567";
contacts.Insert(mario);

contacts.Insert(new Document()
.Append("Name", "Humberto")
.Append("Phone", "5555555")
);

Puede observarse dos formas de crear documentos. Una vez teniendo dos contactos (Mario y Humberto). Voy a actualizar al contacto con el nombre “Mario”. Aprovechando que estoy usando una base de datos no relacional, cambiaré las campos del documento, para ello utilizo el método Update de la colección contacts pasando como primer parámetro el nuevo documento y como segundo parámetro un documento que me sirve como selector

contacts.Update(
new Document()
.Append("FirstName", "Mario")
.Append("LastName", "Cornejo")
.Append("Phone", "1234567")
, new Document()
.Append("Name", "Mario")
);

Para hacer solo la actualización del campo teléfono del contacto con el nombre “Humberto” puedo hacer lo siguiente:

var humberto = contacts.FindOne(new Document().Append("Name", "Humberto"));
humberto["Phone"] = "4444444";
contacts.Update(humberto);
Aquí utilice el mismo método Update, pero solo le pase como parámetro el documento actualizado. Como se puede ver, la forma de realizar las operaciones desde C# es muy similar a como lo haríamos desde la consola usando la aplicación Mongo.exe

miércoles, febrero 03, 2010

Iniciando con MongoDB

Recientemente he empezado a jugar con la base de datos no relacional MongoDB, grabe un mini-screencast donde muestro la características básicas de esta base de datos orientada a documentos.

También puedes ver el video directamente desde www.screencast.com

lunes, diciembre 21, 2009

Compartir DataContext por cada HTTP Request

Trabajando en proyectos donde, por petición especifica del cliente, debo usar LinqToSql para mi acceso a datos. Donde además se me ha pedido usar las entidades generadas por LinqToSql  como mis entidades de negocio. Al abstraer mi acceso a datos con repositorios, Esto con la finalidad de poder hacer pruebas unitarias en mi capa de servicios, me encontré con la necesidad de compartir el DataContext a través de mis repositorios, en si lo que necesitaba era tener un solo DataContext por cada petición HTTP.
Para ello mis repositorios reciben en el constructor un IDataContextFactory la cual será la encargada de pasarle el datacontext a los repositorios
public interface IDataContextFactory<T> where T: DataContext, new()
{                                                                  
    T GetCurrentDataContext();                                     
    void DisposeCurrentDataContext();                              
}                                                                  

Así mis repositorios no necesitan saber de donde viene el datacontext. Aquí esta la implementación de esta interfaz para tener un datacontext por request

public class WebDataContextFactory<T>: IDataContextFactory<T> where T : DataContext, new()
{                                                                                         
    public T GetCurrentDataContext()                                                      
    {                                                                                     
        var dataContext = HttpContext.Current.Items[typeof(T)] as T;                      
        if (dataContext == null)                                                          
        {                                                                                 
            dataContext = new T();                                                        
            HttpContext.Current.Items[typeof(T)] = dataContext;                           
        }                                                                                 
                                                                                          
        return dataContext;                                                               
    }                                                                                     
                                                                                          
    public void DisposeCurrentDataContext()                                               
    {                                                                                     
        var dataContext = HttpContext.Current.Items[typeof(T)] as T;                      
        if (dataContext != null)                                                          
            dataContext.Dispose();                                                        
    }                                                                                     
}                                                                                         

lo que hago es guardar el datacontext dentro del diccionario Items del actual HttpContext, el cual esta vivo solo para ese request y se puede utilizar el evento request end del HttpAplication para hacer dispose del datacontext a través del IDataContextFactory

martes, diciembre 01, 2009

TDD con Fluent Validation Parte 2

En el post anterior (screencast) mostré como escribir las pruebas para un validador que usa la librería FluentValidation, debido a que se me acababan los 5 minutos, solo mostré las pruebas. en esta ocasión muestro como escribir el código para satisfacer dichas pruebas, el cual es muy simple. el screencast dura solo 2 minutos

aquí el link para verlo desde jing

sábado, noviembre 21, 2009

TDD con Fluent Validation

En este mini-screencast (5 min) muestro como escribir las pruebas unitarias para un validador que será escrito utilizando la librearía FluentValidation

Para ver el video desde el sitio de jing haz clic aquí

martes, octubre 27, 2009

Munq - Inversión de Control para ASP.NET MVC

Buscando un contenedor de inversión de control (IoC Container en ingles) ligero para utilizar en una aplicación ASP.NET MVC me encontré con Munq el cual esta escrito a partir del código de Funq. Me pareció muy fácil de configurar así que grabe un pequeño screencast (4 min), usando jing, en el cual muestro como configurarlo para usarlo con la aplicación que crea la platilla de nuevo proyecto ASP.NET MVC 1 en Visual Studio.

Para ver directamente desde el sitio de jing haz clic aquí.

miércoles, octubre 21, 2009

TDD ¿Por qué escribir primero las pruebas?

Hace poco leí el blog post de Eber Irigoyen donde escribe sobre duct tape programming. Lo que me llamo la atención en ese post es que Eber mencionó que al escribir pruebas, estas no las hace antes de escribir el código necesario para que las pruebas pasen e incluso menciona que la idea de escribir la prueba primero la considera algo tonta (no son sus palabras exactas pero es la idea). En lo personal la idea de escribir la prueba antes del código lo considero como una buena practica y no pensaría que es algo tonto.

Muchas de las veces cuando se me solicita realizar un nuevo programa o agregar funcionalidad a uno ya existente primero se realiza una entrevista con el usuario final, analista de negocio o cliente (de ahora en adelante lo llamaré cliente) que solicita la funcionalidad. Para que ahí explique a detalle que es lo que necesita. En ocasiones al cliente se le dificulta expresar que es lo que realmente necesita y eso se debe en gran parte porque el tampoco esta seguro que es lo que realmente necesita.

He notado que esto sucede principalmente cuando el cliente, al empezar a explicar el problema y lo que desea lograr con la nueva funcionalidad, esta pensando en la solución que le ayudará a resolver su problema. Inicia explicando como es que ve su solución en lugar de explicar el problema o lo que quiere lograr con ello. En ocasiones se empieza a discutir la implementación de esa solución y que problemas pudiéramos encontrar, después se discute como es que se podría ayudar a resolver esos problemas. Así la discusión puede continuar centrándose en como resolver los problemas de una posible solución que pudiera o no ser la ideal.

Si el desarrollo se centra en hacer que la posible solución funcione, se corre el riesgo que al terminar el desarrollo, esta no cumpla con las expectativas del cliente, ya que lo que se tomo en cuenta para desarrollarla fue la posible solución en lugar de lograr que el problema inicial del cliente se resolviera. Esto hace que el cliente se de cuenta que la solución no le sirve del todo pero el desarrollador siente que cumplió porque hizo que funcionara lo que le pidieron.

Cuando el cliente se centra primero en explicar el problema y en especificar lo que espera lograr, en lugar de pensar en la posible solución. Es entonces cuando yo como profesional puedo trabajar en un programa que resuelva su problema y logre lo que él espera.

Del mismo modo cuando el desarrollador inicia escribiendo el código que resuelva un problema sin especificar antes que es lo que quiere lograr con ello. Es posible que termine escribiendo código que no va a necesitar. Esto es porque se centra en escribir una solución robusta en lugar de solo resolver el problema.

Por eso que pienso que el escribir lo que esperamos del código, como una prueba unitaria, antes de escribir la implementación nos da la ventaja de centrarnos en lo que realmente es importante: cumplir con al expectativa. Y no tanto en hacer que nuestra posible solución funcione. De igual forma ayuda a no escribir código que posiblemente no se necesite, ya que la prioridad es hacer que la prueba unitaria (especificación) pase.

Considero que es benéfico que al iniciar el desarrollo de nueva funcionalidad primero se especifiquen las expectativas que se tienen sobre ella y después se evalúe en base a esas especificaciones. Las expectativas se escriben usando pruebas unitarias y es por eso que me gusta que las pruebas se escriban primero.

El desarrollo guidado por pruebas o TDD (Test Driven Development) no solo se trata de las pruebas. TDD es una tarea de diseño.

viernes, octubre 09, 2009

VB XML Literals – Parte 3 LinqToXml

Siguiendo con la serie de post sobre VB XML Literals en esta ocasión en lugar de copiar y pegar el código utilicé Jing para grabar un screencast de 5 minutos donde explico como buscar dentro de un archivo xml usando LinqToXml en VB XML Literals

Ver screencast desde el sitio Jing

Post Relacionados
VB XML Literals Parte 2
VB XML Literals Parte 1

lunes, octubre 05, 2009

VB XML Literals - Parte 2

En la parte 1 de esta serie de posts sobre XML Literals expliqué en el ejemplo como cargar un objeto a partir de un archivo xml. Ahora veré el caso contrario: A partir de un objeto Order creare un archivo xml con la información de la orden. Este es el test con que comprobaré que mi método esta funcionando:

[TestMethod]
public void should_save_order_to_file()
{
var fileName = @"..\..\Order_Temp.xml";

if (File.Exists(fileName)) File.Delete(fileName);

var order = CreateSampleOrder();

var orderXmlTasks = new OrderXmlTasks();
orderXmlTasks.SaveToFile(fileName, order);

File.Exists(fileName).Should().Be.True();

var fileLines = File.ReadAllLines(fileName);
var expectedLines = CreateExpectedXml();
for (int i = 0; i < fileLines.Length; i++)
{
var line = fileLines[i].Trim();
line.Should().Be.EqualTo(expectedLines[i]);
}
}

public Order CreateSampleOrder()
{
return new Order
{
Id = 321,
Customer = "Peter Griffin",
Items = new List<OrderItem>
{
new OrderItem { ProductId = 3, Quantity = 1, Price = 2.05m, Description = "product x" },
new OrderItem { ProductId = 7, Quantity = 4, Price = 3.45m, Description = "product y" },
new OrderItem { ProductId = 8, Quantity = 9, Price = 5.50m, Description = "product z" },
}
};
}

public string[] CreateExpectedXml()
{
var xml = new List<string>();

xml.Add("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
xml.Add("<order id=\"321\" xmlns=\"urn:schemas-developeando-com:xmlLiterals\">");
xml.Add("<customer>Peter Griffin</customer>");
xml.Add("<items>");
xml.Add("<item productId=\"3\" quantity=\"1\" price=\"2.05\">product x</item>");
xml.Add("<item productId=\"7\" quantity=\"4\" price=\"3.45\">product y</item>");
xml.Add("<item productId=\"8\" quantity=\"9\" price=\"5.50\">product z</item>");
xml.Add("</items>");
xml.Add("</order>");

return xml.ToArray();
}

Lo que hace el test es crear una orden de ejemplo (CreateSampleOrder), escribir los datos de la orden en un archivo xml y después leo el archivo generado y lo comparo con el xml esperado (CreateExpectedXml)

Generar xml usando XML Literals es tan simple como solo escribir el XML y agregar expresiones donde queremos insertar código. Entonces el código para que la prueba pase queda así:

Public Sub SaveToFile(ByVal FileName As String, ByVal Order As Order)
Dim xml = <order id=<%= Order.Id %>>
<
customer><%= Order.Customer %></customer>
<
items>
<%= From item In Order.Items _
Select <item
productId=<%= item.ProductId %>
quantity=<%= item.Quantity %>
price=<%= item.Price %>>
<%= item.Description %>
</item> %>
</items>
</
order>
xml.Save(FileName)
End Sub

Como se puede apreciar solo declaro una variable y le asigno el xml, usando expresiones para indicar donde quiero escribir los valores de las propiedades del objeto Order. Para los items utilizo una expresión LINQ para indicar que por cada item agregue un elemento <item> y asigno el valor a los atributos y el valor de la descripción en el texto interno.