10.29.2009

Expresiones Lambda en VB.NET 9.0

Explorando un poco las nuevas facilidades del lenguaje VB.NET en el framework 4.0, me encontré con algo que realmente me llamó la atención positivamente: expresiones lambda. Una de las formas de aprovechar las expresiones lambda es utilizandolas en las extensiones de métodos que tienen diversas clases, las cuales nos permiten de forma sencilla realizar operaciones que normalmente tomarían muchas líneas de código. Veamos el siguiente ejemplo:

En versiones anteriores se podía en VB.NET – y también en C# – utilizar la extensión del método FindAll de una lista para obtener una sub lista con todos los ítems que hicieran match con el criterio del predicado enviado por parámetro al método de extensión. El predicado de esta función, por lo general es un delegate que apunta a un método definido en otro lugar, o es un método anónimo. El siguiente código nos muestra esta situación:

image

Como podemos ver en la figura, tenemos una lista de enteros la cual se inicializa de 1 a 10. Seguidamente vamos a crear otra lista de enteros y la vamos a inicializar solamente con los números pares de la lista inicial. Esto lo logramos utilizando un predicado en el método de extensión FindAll de la clase List(Of T ), este predicado contiene la dirección de un método el cual se va a ejecutar por cada ítem contenido en la lista.

Si usamos una expresión lambda, el método será un poco más sencillo de escribir, tal y como podemos ver en el siguiente código:

image

El método anterior funciona de forma idéntica al método en donde utilizamos un delegate, pero no tiene una referencia a otro método que haga la operación deseada, en cambio la expresión lambda escrita como predicado del método FindAll se ejecuta de la misma manera que se ejecuta el delegate a la función ObtenerPares.

10.11.2009

Webcasts – EntityFramework y Mashups

En esta ocasión voy a darles solamente un link de un par de videos en el que tuve la suerte de participar en conjunto con Jose Guay de Guatemala, Carlos Lone de Guatemala y Ricardo Jiménez de Microsoft Costa Rica. El primer video es una conversación que tuvimos acerca al entity framework. El segundo video es acerca de mashups. Espero lo disfruten.

Aqui esta el link del entity framework y el otro link respecto a mashups.

Technorati Tags: ,

9.27.2009

Entity Framework: Eliminando Entidades de una Lista y Refrescando el UI

En el post anterior vimos como implementar la interface IEquatable<T> para poder utilizar los métodos de la lista sobre las entidades tales como Contains e IndexOf. En este post vamos a ver como eliminar entidades de la lista y notificar este evento al UI que tenga binding con la lista afectada. Al mismo tiempo vamos a aplicar la modificación a la base de datos.

Eliminando una Entidad de la Lista y Notificando el UI

El primer paso para eliminar una entidad de la lista que tenemos ligada a nuestro UI es definir como vamos a llevar a cabo este procedimiento. En primera instancia vamos a agregar dos botones más a nuestra pantalla, uno para eliminar y otro para aplicar cambios. El diseño de la pantalla quedará como se observa a continuación

image

El siguiente paso es cambiar la forma en que hacemos binding de los datos desde el EF. Anteriormente utilizabamos una lista para almacenar nuestras entidades y así presentarlas en el UI, ahora vamos a cambiar esa lista por una colección del tipo ObservableCollection. Las colecciones de este tipo tienen la particularidad que notifica cuando se agrega o se elimina un elemento de la colección, o cuando se recarga la misma. Para esto, declaramos la colección del tipo de la entidad Empresa como lo hicimos en el post anterior.

ObservableCollection<Empresa> m_Empresas = new ObservableCollection<Empresa>();

public ObservableCollection<Empresa> Empresas
{
get { return m_Empresas; }
set { m_Empresas = value; }
}


El siguiente paso es hacer el binding desde el EF y ligarlo con el control a través del cual queremos desplegar los datos. En nuestro caso tenemos una función que nos devuelve la colección de empresas – ObtenerEmpresa – y en el load de la forma, procedemos a ligar la colección al Grid de Empresas.



private void Window_Loaded(object sender, RoutedEventArgs e)
{
Empresas = ObtenerEmpresas();
dgEmpresas.ItemsSource = Empresas;
}
public ObservableCollection<Empresa> ObtenerEmpresas()
{
UseCasesEntities entities = GetEntity();
var Empresas = from e in entities.Empresa select e;
return new ObservableCollection<Empresa>(Empresas.ToList());
}



El método GetEntity() es un método que utiliza un patrón singleton para obtener siempre el mismo contexto del Entity Framework y así poder eliminar, modificar, o agregar entidades al repositorio de datos.



static UseCasesEntities entities;

private static UseCasesEntities GetEntity()
{
if (entities == null)
entities = new UseCasesEntities();
return entities;
}



El siguiente paso es agregar el código necesario para poder eliminar la entidad de la colección cuando el usuario así lo requiere, es decir cuando seleccione una entidad y de clic en el botón de eliminar. En este caso obtenemos la entidad seleccionada casteando la fila seleccionada a un objeto tipo Empresa, seguidamente y gracias a la implementación de IEquatable<T> podemos utilizar el método remove de la colección para remover la entidad de la colección. También procedemos a marcar el objeto seleccionado como eliminado dentro del contexto del entity framework.



private void btnEliminar_Click(object sender, RoutedEventArgs e)
{
Empresa tmpEmpresa = dgEmpresas.SelectedItem as Empresa;
Empresas.Remove(tmpEmpresa);
GetEntity().DeleteObject(tmpEmpresa);
}



Con estos cambios, ya tenemos la funcionalidad a nivel de UI, si ejecutamos el código anterior, vamos a eliminar los ítems de la lista, y sin refrescar la lista, obtenemos el cambio en el UI.



Aplicando los cambios en el UI



Una vez realizados los cambios en el UI, debemos persistir los cambios en la base de datos. Para llevar a cabo esta funcionalidad, simplemente agregamos el siguiente código al manejador del evento clic del botón aplicar.



private void btnAplicar_Click(object sender, RoutedEventArgs e)
{
GetEntity().SaveChanges();
}





En este caso, solamente ejecutamos el método SaveChanges para persistir el cambio o los cambios a la base de datos.



9.12.2009

Extendiendo el Entity Framework – Comparación y Búsqueda de Entidades

Una de las tareas más comunes cuando trabajamos con el Entity Framework es la búsqueda de las entidades en una lista y la comparación de las mismas. El EF nos provee la facilidad de agregar código para comparación a través de la Interface IEquatable y las clases parciales.

Interface IEquatable<T>

La interface IEquatable<T> de acuerdo al msdn se define como una interface que define un metodo de igualdad, el cual determina la igualdad de las instancias del tipo implementado. Por otro lado y para aclarar por adelantado, la Interface IComparable<T> define un metodo de comparación generalizado para ordenamiento de instancias.

IEquatable<T> se usa normalmente por colecciones genericas tales como List<T> y LinkedList<T> para ser utilizado en métodos tales como Contains, IndexOf, Remove, etc. Esta interface se debe de implementar en cualquier objeto que se va a almacenar en colecciones genéricas.

Extendiendo una Entidad con IEquatable<T>

El primer paso para extender una entidad del Entity Framework es crear una clase que contenga este código adicional. En este caso, vamos a extender la entidad Empresa y por lo tanto, vamos a crear una clase parcial que igualmente se va a llamar empresa. Para esto procedemos a agregar la clase en el proyecto donde definimos el modelo del Entity Framework.

imageSeguidamente procedemos a poner la clase recién creada como pública y parcial; esto va a permitir que esta clase se compile en conjunto con la clase generada por el EF en una sola clase,  por lo que toda la funcionalidad que agregemos a esta clase será parte de la clase Empresa del EF. Además, por estar en una clase parcial, si tenemos que regenerar el modelo, no vamos a perder la lógica incluída.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Samples
{
public partial class Empresa
{
}
}
Como podemos ver en la siguiente figura, la clase que genera el EF es también parcial y por lo tanto podemos agregar la funcionalidad que deseamos.


image Seguidamente procedemos a implementar la clase IEquatable<T> para poder definir como vamos a hacer las comparaciones en nuestra entidad. Nótese como el método definido en el contrato de la interface – Equals – recibe otra entidad de tipo empresa para llevar a cabo la comparación.



public partial class Empresa : IEquatable<Empresa>
{
#region IEquatable<Empresa> Members

public bool Equals(Empresa other)
{
//Aquí vamos a implementar nuestra comparación
return true;
}

#endregion
}



Para este caso especifico, quiero que la empresa se pueda comparar tanto por el campo Id como por el nombre, es decir, buscarla en la lista por nombre y buscarla por Id para cuando por ejemplo el item se selecciona desde un combo box.



public partial class Empresa : IEquatable<Empresa>
{
#region IEquatable<Empresa> Members

public bool Equals(Empresa other)
{
if (this.Id == other.Id || this.Nombre == other.Nombre)
return true;
return false;
}

#endregion
}



Como podemos ver, el método Equals contiene la definición de comparación que nosotros creamos conveniente para poder utilizar la entidad en nuestra lógica de negocios.



Ahora vamos a utilizar nuestra entidad para diferentes propósitos. Inicialmente vamos a tener una pantalla para buscar empresas por nombre tal y como luce a continuación.



image La idea es buscar entre las empresas del grid la que deseamos y desplegarla en un diálogo modal. Este dialogo que se presentará de forma modal es el siguiente:



imageEl siguiente paso es crear la lógica para presentar un detalle de una empresa en el dialogo anterior, lo cual hacemos con el siguiente código:



public partial class frmEmpresa : Window
{
private Empresa m_Empresa;

public Empresa EmpresaProp
{
get { return m_Empresa; }
set { m_Empresa = value; }
}

public frmEmpresa(Empresa pEmpresa)
{
InitializeComponent();
EmpresaProp = pEmpresa;
txtNombre.Text = EmpresaProp.Nombre;
txtDireccion.Text = EmpresaProp.Direccion;
txtTelefono.Text = EmpresaProp.Telefono;
txtEmail.Text = EmpresaProp.Email;
}

public frmEmpresa()
{
InitializeComponent();
}

private void btnCerrar_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}


Ahora vamos a programar el código necesario para buscar la entidad deseada en la lista que hemos cargado en el grid y si la encontramos, procedemos a invocar la forma anterior para presentar su detalle.



public partial class BuscarEmpresa : Window
{
List<Empresa> m_Empresas = new List<Empresa>();

public List<Empresa> Empresas
{
get { return m_Empresas; }
set { m_Empresas = value; }
}
public BuscarEmpresa()
{
InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
Empresas = ObtenerEmpresas();
dgEmpresas.ItemsSource = Empresas;

}

public List<Empresa> ObtenerEmpresas()
{
UseCasesEntities entities = new UseCasesEntities();
var Empresas = from e in entities.Empresa select e;
return Empresas.ToList();
}

private void btnBuscar_Click(object sender, RoutedEventArgs e)
{
Empresa empresaTmp = new Empresa();
empresaTmp.Nombre = txtEmpresa.Text;

if (Empresas.Contains(empresaTmp))
{

frmEmpresa frm = new frmEmpresa(Empresas[Empresas.IndexOf(empresaTmp)]);
frm.ShowDialog();
}
else
MessageBox.Show("Empresa no existe", "Mensaje");
}
}



El código que nos interesa es el código del evento click del botón buscar. Lo primero que hacemos es crear una instancia de la entidad empresa y proceder a asignarle el valor digitado por el usuario en el textbox. Seguidamente, vamos a pedirle a la lista de empresas ( declarada al inicio de la clase ) a través del método Contains, si tiene una entidad igual a la que le estoy enviando. Nótese que aunque no he cargado todos los campos, el llamado a Contains busca la implementación de la interface IEquatable<T> para hacer la búsqueda, por esta razón si digitamos el nombre de alguna empresa que exista, el método lo encuentra. Si el existe, el siguiente paso es desplegarlo en la pantalla de detalle pasándola por parámetro. Para lograr esta funcionalidad tenemos que ir a obtener la entidad de la lista, lo cual se logra con una combinación de un método de la lista – IndexOf - y el indexador de la misma []. IndexOf utiliza la comparación que nos provee la interface IEquatable<T>. El resultado al ejecutar el ejemplo anterior es el siguiente:



imageEn los post siguientes vamos a profundizar en este tema.













9.02.2009

SpellCheck en WPF

Una característica interesante que me encontré trabajando en el desarrollo de una aplicación WPF es la posibilidad de tener SpellCheck en la edición de texto en los controles TextBox y RichTextBox. Además, la forma de lograrlo es muy simple. Inicialmente se habilita la propiedad SpellCheck.IsEnabled="True" y se indica cual lenguaje se desea para hacer el spell check con la propiedad Language. La siguiente figura nos muestra como llevar a cabo esta configuración:

image Cuando ejecutamos la aplicación y escribimos palabras en español incorrectas, estas serán subrayadas con rojo y si le damos botón derecho sobre la palabra, un context menu nos hará sugerencias para reemplazar la palabra incorrecta.

image El diccionario que se utiliza para realizar este spellcheck en este momento soporta 4 lenguajes: inglés, español, francés y alemán. La lista de sugerencias son una copia del diccionario de Microsoft Office 2007 y al ser una copia, no se requiere tener instalado Office en la máquina.

Technorati Tags: ,,

8.30.2009

Manejo de Excepciones en WPF

En una ocasión estando desarrollando un proyecto en WPF con varios desarrolladores más, surgió la pregunta ¿Cómo manejar las excepciones en WPF? Y es que esta pregunta puede parecer sencilla, ya que como todos sabemos en .NET existe el manejo de excepciones a través de la estructura try … catch … finally. Sin embargo, cuando se esta trabajando en el UI de un proyecto en WPF y varios desarrolladores hacen y modifican eventos y procedimientos en las pantallas – validación, llamadas a lógica de negocios y manejo de errores – es importante saber como va a reaccionar la aplicación a errores no esperados en secciones de código en donde no se han programado bloques de control de errores. En otras palabras lo que se busca es una forma central de manejar las excepciones, tal y como se logra hacer de manera sencilla en ASP.NET cuando en el archivo web.config le indicamos a la aplicación que en caso de un error no previsto y no atrapado, despliegue el error en una página específica. Durante esta experiencia investigué cuál era el modo más cercano de lograr este comportamiento en WPF y este post el resultado de esta investigación.

En primera instancia, si existe un lugar central desde donde crear un método que nos permita manejar los errores que se disparen en la aplicación WPF y que no hayan sido manejados por bloques de try…catch previamente. Este lugar es en el archivo App.xaml.cs – en el caso de C#. En esta clase podemos definir un manejador de eventos para el evento de aplicación DispatcherUnhandledException el cual se va a disparar cada vez que ocurre un evento inesperado. A continuación el código de la clase App.

using System.Windows.Threading;



/// <summary>
///
Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
string errorMessage = string.Format("Ocurrió una excepción inesperada. {0}{1}"
, Environment.NewLine, e.Exception);
MessageBox.Show(errorMessage, "Error atrapado en el obj Application");
e.Handled = true;
}
}


En este caso vamos a necesitar agregar el namespace using System.Windows.Threading que es el namespace donde se encuentra declarado el tipo DispatcherUnhandledExceptionEventArgs el cual es el que vamos a utilizar como parámetro para manejar el error. Esta variable – e en nuestro caso – contiene una referencia a la excepción que no ha sido manejada y una bandera indicando si la excepción ha sido manejada o no. Es importante destacar que este evento se va a disparar solamente en el thread del UI, otras excepciones lanzadas desde otro thread no van a ser atrapadas – lo veremos en el ejemplo. En el archivo App.xaml, vamos a agregar el evento y su correspondiente manejador, el cual en nuestro caso es App_DispatcherUnhandledException.



image Seguidamente procedemos a agregar el código correspondiente en WPF y XAML. Primeramente vamos a agregar 3 botones, el primero de ellos no va a manejar la excepción y por lo tanto debe de ser atrapada en el manejador global de errores, el segundo de ellos atrapa la excepción localmente ya que tiene un bloque try … catch y el último lanza una excepción en otro thread, por lo tanto no es manejada en nuestro evento de manejo de errores global a la aplicación. El código en cs es el siguiente.



private void btnGuardar_Click(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
try
{
throw new NotImplementedException();
}
catch (NotImplementedException ex)
{

MessageBox.Show(ex.Message, "Error manejado en la ventana");
}
}

private void button2_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate
{
throw new NotImplementedException();
};
worker.RunWorkerAsync();
}



Del lado de XAML, agregamos los 3 botones que van a disparar los eventos anteriores.



image La pantalla en modo gráfico luce así:



image Al ejecutar el primer botón – el error se maneja en el App.xaml.cs - el resultado es el siguiente:



image Al utilizar el botón en donde se maneja el error localmente el resultado es el siguiente:



image





Por último, al lanzar una excepción en otro thread no se dispara ningún error y este no se maneja de forma global.



image



De esta manera podemos manejar de manera unificada las excepciones sin manejar en aplicaciones WPF.







Technorati Tags: ,,

8.25.2009

Manejo del Scope con Unity

Cuando se trabaja con IoC containers existe un factor que en muchas ocasiones se ignora a la hora de crear instancias dinámicamente: el scope del objeto que estamos creando. En este post vamos a analizar las opciones para el manejo del scope cuando utilizamos el Unity Application Block.

¿Qué es el Scope?

El scope – alcance – de un objeto es la cantidad de tiempo o las llamadas a los métodos en los cuales un objeto existe. Es decir, el scope es el contexto bajo el cual un identificador se refiere a la misma instancia. También podemos definir el scope como la cantidad de tiempo que el estado de un objeto persiste. Cuando el contexto del scope finaliza, cualquier objeto ligado a este scope queda fuera de alcance y no pueden inyectarse de nuevo en otras instancias.

El Scope y los IoC

La verdadera ventaja del scope en los IoC es que permite modelar el estado de los objetos de forma declarativa. Esto se logra diciendole al inyector que una llave en particular esta ligada a un scope, y por lo tanto se puede manipular la construcción y el lige entre objetos en el contexto del inyector.

El aplicar correctamente el manejo del scope significa que un código trabajando en un contexto particular no esta conciente del contexto en que se ejecuta. Es responsabilidad del inyector el administrar estos contextos. Esto significa que se tiene una separación entre la aplicación y la infraestructura, sino que también estos servicios pueden ser utilizado para muchos propósitos alternando simplemente el scope seleccionado. Para visualizar mejor esto vamos a trabajar con un ejemplo.

deptartment.Print("drojas", "Project Plan", injector.Resolve<Printer>());
deptartment.Print("jcalvo", "work items", injector.Resolve<Printer>());
deptartment.Print("palfaro", "todo's", injector.Resolve<Printer>());


Supongamos que en un departamento de una empresa trabajan 3 usuarios, y cada uno tiene un documento que mandar a imprimir. Basándonos en el ejemplo anterior podríamos decir que la impresora la utiliza primero drojas, seguidamente jcalvo y por último palfaro. Si la impresora es de poca capacidad y los documentos de drojas y jcalvo son muy grandes, puede ser que palfaro se quede sin tinta o sin hojas para imprimir.



image



En este caso el injector distribuye la tinta a través de la misma impresora – misma instancia - entre todos los que van imprimiendo. Este es un ejemplo del contexto: Todos los trabajadores del departamento comparten la misma área, y por lo tanto comparten la impresora. En este caso la impresora esta accesible a través de un scope del tipo singleton.





Otro ejemplo de contexto sería cuando cada uno de los trabajadores del departamento tienen su propia impresora. Teoricamente, si utilizamos el ejemplo anterior, podríamos decir que cada trabajador imprime en su impresora; y digo teoricamente porque esto no es absolutamente cierto, ya que si palafaro manda a imprimir dos veces el mismo documento, estaríamos utilizando dos impresoras diferentes:



deptartment.Print("drojas", "Project Plan", injector.Resolve<Printer>());



deptartment.Print("jcalvo", "work items", injector.Resolve<Printer>());



deptartment.Print("palfaro", "todo's", injector.Resolve<Printer>());



deptartment.Print("palfaro", "todo's", injector.Resolve<Printer>());



En este caso, estamos trabajando sin alcance, y lo que estamos diciendole al injector es que debe de crear una nueva instancia por llamado.



Controlando el Scope con Unity


El scope en Unity se puede controlar vía configuración o vía código. El contenedor de Unity administra la creación y la resolución de objetos basado en el scope que se especifica cuando se registra el tipo o de lo contrario se utiliza el scope por defecto – sin scope.



Cuando se registra un tipo utilizando el metodo RegisterType,  el comportamiento por defecto es crear una nueva instancia del tipo solicitado cada vez que se invoca el metodo Resolve o ResolveAll. El contenedor no mantiene guarda una referencia al objeto. Sin embargo, cuando se desea un comportamiento Singleton para los objetos que se van a instanciar, el contenedor mantiene una referencia a los objetos creados.



Cuando se registra un objeto existente utilizando el método RegisterInstance el comportamiento por defecto es que el contenedor tome la administración del tiempo de vida del objeto que se pasa como parámetro al objeto. Esto significa que el objeto se mantiene en el scope mientras el contenedor este en el scope; una vez que el contenedor salga del scope o cuando se elimina la instancia del contenedor explícitamente, el objeto registrado será inalcanzable.



Unity utiliza lo que se conoce como “lifetime managers” para controlar como se guardan las referencias a las instancias de los objetos y como el contenedor elimina estas instancias. Unity incluye 3 “lifetime managers” que pueden ser utilizados directamente en el código.





  1. ContainerControlledLifetimeManager: Unity retorna la misma instancia del tipo registrado cada vez que se llama al metodo Resolve, ResolveAll o cuando el mecanismo de dependencia inyecta instancias en otras clases. Este es el mecanismo para implementar un comportamiento Singleton. Este lifetime manager se utiliza por defecto para el metodo RegisterInstance si no se especifica algún otro. Si se desea un comportamiento singleton que se crea cuando se utiliza el método RegisterType, se debe de especificar de forma explícita.




  2. ExternallyControlledLifetimeManager: Este manager permite registrar tipos y objetos existentes en el contenedorm, pero mantiene una referencia “débil” a los objetos que se crean utilizando Resolve y ResolveAll. Unity retorna la misma instancia cuando se utilizan estos métodos, pero el contenedor no mantiene una referencia fuerte a los mismos luego de crearlos, por lo que el Garbage Collector puede eliminar los objetos si no existe código que mantenga una referencia fuerte a los objetos creados.




  3. PerThreadLifetimeManager: Unity retorna la misma instancia por thread del tipo registrado cada vez que se invoca el método Resolve o ResolveAll. Este lifetime manager implementan un singleton por thread, por lo tanto retorna diferentes objetos para cada thread.





    1. Si se utiliza el método RegisterType, Unity crea una nueva instancia la primera vez que se resuelve el tipo en un thread específico utilizando Resolve o ResolveAll. Las siguientes invocaciones retornan la misma instancia en el thread.




    2. Si se utiliza el método RegisterInstance, se obtiene el mismo comportamiento que ofrece el método RegisterType. Por esta razón no se recomienda utilizar el método RegisterInstance para registrar un objeto utilizando este lifetime manager.





A continuación vamos a ver el uso de estos lifetime managers. Inicialmente vamos a crear una interface que se llamará IPrinter la cual tiene un método para imprimir y una propiedad llamada Name donde vamos a almacenar el código hash de la instancia utilizada, esto nos permitira ver si la instancia es un singleton o no.



public interface IPrinter
{
string Name { get; set; }
string Print(string document);
}


Seguidamente vamos a crear dos clases que implementan esta interface: LaserPrinter e InkPrinter. Estas clases son las que vamos a registrar e instanciar utilizando Unity y sus lifetime managers.



public class LaserPrinter : IPrinter
{
public string Name { get; set; }
public LaserPrinter()
{
Name = this.GetHashCode().ToString();
}
public string Print(string document)
{
return "Imprimiendo el documento: " + document + " en laser";
}
}

public class InkPrinter : IPrinter
{
public string Name { get; set; }
public InkPrinter()
{
Name = this.GetHashCode().ToString();
}
public string Print(string document)
{
return "Imprimiendo el documento" + document + " en Tinta";
}
}



Seguidamente creamos en el método main, el código necesario para registrar y crear las instancias utilizando el contenedor de Unity.



static void Main(string[] args)
{
using (IUnityContainer unityContainer = new UnityContainer())
{
//La impresora laser la vamos a registrar como un singleton
unityContainer.RegisterType<IPrinter, LaserPrinter>("Laser", new ContainerControlledLifetimeManager());
//La impresora de tinta le vamos a dar un tiempo de vida pasajero, es decir, vamos a crear
//una instancia por llamado.
unityContainer.RegisterType<IPrinter, InkPrinter>("Ink");

//Impresora con hash propio
IPrinter printer = unityContainer.Resolve<IPrinter>("Ink");
Console.WriteLine(printer.Print("Tareas"));
//Impresora con singleton
IPrinter printer2 = unityContainer.Resolve<IPrinter>("Laser");
Console.WriteLine(printer2.Print("Errores"));
//Impresora con singleton
IPrinter printer3 = unityContainer.Resolve<IPrinter>("Laser");
//Impresora con hash propio
IPrinter printer4 = unityContainer.Resolve<IPrinter>("Ink");

Console.WriteLine(printer.Name);
Console.WriteLine(printer2.Name);
Console.WriteLine(printer3.Name);
Console.WriteLine(printer4.Name);
}
}



El resultado al ejecutar el código anterior es el siguiente:



image 



La pregunta que nos surge ahora es: ¿cuándo usar un singleton o cuando usar un alcance pasajero? Pues desde mi punto de vista, un buen lugar para utilizar un singleton es una capa de acceso a datos, ya que por lo general estas operaciones son unitarias y especificas – leer datos, escribir un dato – y no necesitamos realmente crear una nueva instancia para poder tener acceso a estos componentes. Igualmente, operaciones en donde las operaciones para inicializar un objeto son muy “pesadas” y en donde estas configuraciones de arranque son solo de lectura, son buenos candidatos para un singleton.



Technorati Tags: ,,,

8.15.2009

¿Por qué es importante el MSE – Managed Service Engine?

En muchas ocasiones cuando estoy en consultorias relacionadas con arquitecturas orientadas a servicios – SOA – tengo que hacer mucho enfasis en el hecho de que tener web services en la organización no significa que tengo una arquitectura orientada a servicios. Al mismo tiempo, se me consulta que papel juega el MSE en la transición hacia una arquitectura orientada a servicios. En este post voy a tratar de aclarar estas dos dudas.

Tener Servicios Web no es tener SOA

Existe la creencia errada respecto a que tener servicios web para ser consumidos tanto internamente como externamente, me da automáticamente una arquitectura orientada a servicios. En realidad cuando implementamos servicios web dentro de nuestra organización estamos creando una arquitectura que se conoce como punto a punto. Esto se puede notar si tenemos muchos servidores Web hospedando los servicios, y/o si tenemos que consumir servicios web de muchas otras organizaciones ya sean externas o internas. En la siguiente figura podemos ver esta arquitectura.

image

En la figura anterior, podemos ver que las aplicaciones hacen referencias directas a servicios que retornan funcionalidad de negocios de las aplicaciones que desean acceder, teniendo en sus referencias el servidor donde estan hospedados estos servicios, el uri del servicio y el contrato de la implementación del servicio. Esto nos pone en desventaja ya que si tenemos que mover algún servicio de servidor, tenemos que actualizar todos los consumidores del mismo, ya que hay una referencia directa al servicio a través del servidor. Peor aún, si estamos consumiendo servicios externos y nos cambian la dirección del servicio, nuestra aplicación no funcionará correctamente si no se nos notifica a tiempo.

Otro problema que tendríamos además del ruteo de los mensajes es el manejo de los errores. Al tener diversas fuentes de donde consumir los servicios, los errores se van a almacenar y administrar en cada uno de los servidores internos o externos, de forma tal que no podemos crear logs centralizados para identificar que sucede en caso de presentarse algún error.

Además, dentro de los patrones de una arquitectura orientada a servicios, el concepto de servicio web no es exclusivo para su implementación. Esto por que en realidad en una arquitectura orientada a servicios yo puedo integrarme con servicios que implementen protocolos diversos tales como HTTP(s), TCP, etc.

Como me ayuda el MSE a tener una Arquitectura Orientada a Servicios

Una de las razones principales por la cual las organizaciones adoptan una arquitectura orientada a servicios es por la promesa de una alta flexibilidad en las aplicaciones. Esta promesa viene del hecho de que una arquitectura SOA diseñada correctamente reduce el tiempo de construcción de las aplicaciones y de los nuevos requerimientos en las aplicaciones ya existentes.

El primer requerimiento de una aplicación SOA bien diseñada es que cualquier aplicación puede ser accesada vía servicios ya sea interna o externamente lo cual permitirá la reutilización.  Esto nos va a permitir desarrollar nuevas aplicaciones que requieran funcionalidad de las aplicaciones ya implementadas de forma más rápida y sencilla porque vamos a requerir menos código para tener acceso a la funcionalidad deseada. Sin embargo, si debo escribir cada servicio desde cero este requerimiento no se puede cumplir o cumplirlo sería muy costos en tiempo e inversión. Si se construyen estos servicios como aplicaciones aisladas, se van a crear servicios con funcionalidades duplicadas, será dificil tener un inventario de servicios disponibles y sus funcionaldiades, los logs de errores de los servicios estarían en cada uno de los servidores que almacenan el servicio, por citar alguno de los inconvenientes que tendríamos si no utilizamos una arquitectura orientada a servicios.

El segundo punto a tratar es que una arquitectura SOA bien diseñada tiene que tomar en cuenta es el cambio constante. En un ambiente empresarial SOA, los servicios tienden a cambiar mientras evolucionan. Estos cambios son de dos tipos: cambios en la interface y cambios en la implementación. El reto esta en encontrar una manera de convivir con la evolución de los servicios y el minimizar el efecto del cambio en los servicios en el consumidor de los mismos.

La pregunta que nos surge ahora es: ¿Qué rol juega el MSE en este escenario? Pues bien, el MSE nos permite llevar a cabo virtualización de servicios. La virtualización de servicios es un esquema de instalación y administración de servicios que nos brinda toda la “plomería” requerida por todos los servicios dentro de la organización. Esto le permite al desarrollador enfocarse en construir nueva funcionalidad y nos brinda una base de funcionalidad donde se requiere conectar con nueva funcionalidad.

Respecto al manejo de los cambios en los servicios, el MSE nos permite manejar este problema a nivel de operación. Este nos da la posibilidad de crear nuevas versiones de las operaciones existentes de los servicios. El MSE nos brinda esta funcionalidad por que el mantiene la interface de la operaciones del servicio conectada pero separada de su implementación, siendo este el principio básico para la virtualización de servicios. A través de la virtualización de servicios se pueden tener tantas versiones de la operación del servicio activas como sea necesarias, pero solamente una puede ser publicada a través del WSDL. Esta característica nos permite soportar la compatiblidad hacia versoines anteriores ya que los usuarios con versiones anteriores pueden serguir consumiendo el servicio y los nuevos usuarios usan el WSDL publicado del nuevo servicio, ambos casos sin complicación alguna. En el momento en que todos los clientes se muevan a la última versión del servicio, las versiones anteriores pueden ser desactivadas. La siguiente figura nos muestra la arquitectura del funcionamiento del MSE y sus funcionalidades en cada uno de los componentes que lo conforman.

image

Technorati Tags: ,,,

8.04.2009

Entendiendo el MSE – Managed Service Engine

Como comenté en un post anterior, el MSE es una herramienta open source que me permite obtener funcionalidad para poder administrar y llevar a cabo una transición entre una arquitectura punto a punto – o servicios web instalados en diversos servidores y web – a una arquitectura orientada a servicios ( SOA ). En este post ahondaré un poco más en los componentes del MSE.

El MSE esta formado de tres componentes principales: el service runtime engine, el catalogo de servicios, y la herramienta de administración para implementar la virtualización de los servicios. El service runtime engine esta implementado como un servicio de windows que administra un conjunto de instancias de hosting de servicios WCF que se configuran automáticamente de la información que se encuentra en el catalogo de servicios.

El MSE esta compuesto de tres componentes internos lógicos: el messenger, el broker y el dispatcher. El messenger es el responsable de la normalización de los mensajes. El broker recibe los mensajes normalizados y es el responsable de seleccionar la versión específica de la operación. El dispatcher es el responsable de la invocación del servicio real que se desea consumir. La comunicación entre estos componentes sucede a través de canales WCF, esto permite distribuirlos en varios servidores y acomodarlos a diferentes infraestructuras que se puedan requerir.

El catalogo de servicios – también conocido como el repositorio de metadatos – contiene los modelos que guían los servicios virtuales contenidos en el runtime del MSE. Lo servicios se importan utilizando la herramienta de administración. Luego de importar el metadata del servicio, se definen los servicios virtuales para el consumo de los clientes.

Cuando se define un servicio virtual, se inicia escojiendo y configurando un binding de WCF. Se puede seleccionar que protocolo utilizar, que características de seguridad habilitar, o cualquier otra característica que soporte el binding seleccionado. También se puede especificar otros comportamietnos para los servicios como inspección de mensajes, transformación, información de versión, y cuales políticas se deben aplicar obligatoriamente utilizando la misma técnica.

El repositorio de metadata esta implementado como una base de datos SQL Server tradicional. Los consumidores no interactúan directamente con la base de datos aunque los datos se pueden publicar con el propósito de ser descubiertos. El MSE mantiene una distinción entre la noción de repositorio y el registro público. El repositorio es donde se encuentran los datos que guían el runtime, y el registro es un almacén separado de metadata de los sevicios que se puede hacer disponible para descubrir y consumir desde afuera.

La siguiente figura nos muestra un diagrama general con la ubicación de algunas de las funcionalidades que están disponibles en el MSE.

image

Technorati Tags: ,,

7.26.2009

Versionando Aplicaciones – Unity – Parte 3

Continuando con la serie de post acerca de IoC – contenedores de dependency injection – en este post vamos a examinar Unity, el cual es un application block que esta disponible gratuitamente desde el sitio de codeplex o a través del sitio de pattern and practices.

Al igual que cualquier otro IoC container, lo que busca unity es desasociar o eliminar la dependencia que existe entre las clases y “mover” esa dependencia a las interfaces. La ventaja con esto en un IoC, es que básicamente al depender de una interface, podemos cambiar la implementación de esa interface en cualquier momento sin necesidad de recompilar la aplicación sino más bien a través de configuración – lo único que necesitamos es cumplir con el contrato.

Trabajando con Unity

En esta ocasión vamos a implementar el mismo ejemplo que presentamos con CastleWindsor del cual presentamos el modelo a continuación:

image El primer paso para hacer funcionar Unity es agregar las referencias necesarias para tener acceso a Unity.

image

Una vez agregadas las referencias, vamos a construir el código necesario para crear la instancia de la clase DoSearch con la alerta del tipo IAlert instanciada utilizando Unity.

image En el código anterior, procedemos a registrar un tipo para el contrato IAlert, en este caso SMSAlert, lo cual nos permite crear una instancia de la clase SearchManager y proceder a asignarle la alerta que corresponde, en este caso utilizamos el metodo Resolve del contenedor. Cuando ejecutamos el código anterior, Unity sabe cual clase tiene que instanciar y procede como se muestra en la siguiente figura.

image El ejemplo anterior no es muy funcional en el sentido de que solamente tenemos una clase para registrar y por lo tanto a la hora de resolver cual clase instanciar, el contenedor solamente debe de instanciar la clase default registrada con el tipo. En el siguiente ejemplo vamos a registrar ambas implementaciones de IAlert con lo cual tendremos que elegir que instancia crear en tiempo de ejecución. Si registramos otro tipo despues de la alerta SMS, entonces el tipo que se instanciaría sería el último registrado.

image El resultado sería el siguiente:

image

La solución para poder elegir cual clase instanciar es especificar un nombre para cada mapa que se va a crear, y a la hora de crear la instancia procedemos a elegir vía ese nombre de mapa, cual tipo instanciar.

image

En este caso especificamos los nombres de SMS y EMail para los mapas y decidimos utilizar SMS. El resultado es el siguiente:

image

Con lo especificado hasta este momento, podemos crear un software factory muy sencillo basándonos en el nombre de la etiqueta del mapa y guardando el nombre en un archivo de configuración o algún medio que permita cambiar la clase a instanciar en tiempo de ejecución.

Pese a lo anterior, Unity nos permite registrar los tipos que vamos a utilizar en un archivo .config y crear las instancias en base a los registrios de los tipos hechos en este archivo. El siguiente ejemplo nos muestra como llevar a cabo esta tarea.

image

En primera instancia se deben agregar las referencias para poder acceder a la configuración del app.config – System.Configuration – y a la configuración de Unity – Unity.Configuration.

image  El siguiente paso es codificar la instanciación de la clase deseada. Para esto, accedemos al archivo de configuración a través del ConfigurationManager y procedemos a configurar la sección de Unity. Seguidamente creamos la clase y procedemos a resolver el tipo. Nótese que en este caso, le indicamos a Unity a través del método Resolve, que queremos una instancia con la etiqueta “SMS”, la cual vamos a agregar al archivo config seguidamente.

image

Primeramente procedemos a registrar la sección que vamos a llamar unity – podríamos llamarla como queramos – y vamos a indicar que assembly para configuración de Unity vamos a utilizar.

Seguidamente procedemos a crear “alias” de los contratos que vamos a instanciar – en este caso IAlert. Por último, dentro de la sección container, agregamos los tipos mapeados para poder instanciarlos. Como podemos ver, en este caso mapeamos SMSAlert a IAlert y le pusimos de nombre SMS, el cual es el nombre que vamos a utililizar para crear la instancia. El nombre PruebaCastleWindsor es el nombre del assembly que se genera y en donde residen los tipos – en este caso una aplicación de consola – y lleva ese nombre porque en el mismo proyecto donde estoy haciendo uso de Unity, hice la prueba de CastleWindsor. El resultado al ejecutar la aplicación es el siguiente:

image

Como hemos visto, Unity también nos sirve para crear aplicaciones fáciles de versionar en tiempo de ejecución – al decir versionar me refiero a instanciar los componentes de negocio que necesitamos dependiendo de reglas de configuración pre establecidas. En post posteriores vamos a ahondar en el uso de Unity.

Technorati Tags: ,,