12.21.2008

¿Qué es SOA – Service Oriented Architecture?

La palabra de moda en los últimos años en el área de desarrollo de software ha sido SOA – Arquitectura Orientada a Servicios. ¿Pero qué significa SOA en realidad?

Básicamente SOA es un cambio significativo en la manera en que nosotros diseñamos y construimos aplicaciones. Esta arquitectura toma la naturaleza abierta de la Web y la convierte en una nueva manera de pensar acerca de las arquitecturas de aplicaciones.

SOA significa integración a través de sistemas diversos. SOA utiliza protocolos estándar e interfaces convencionales – usualmente Web Services – para facilitar el acceso a la lógica de negocios y la información entre diversos servicios. SOA nos brinda los principios y la guía para transformar el conjunto de recursos de TI de la compañía – los cuales son por lo general heterogéneos, distribuidos, inflexibles y complejos -  en recursos flexibles, integrados y simplificados, que pueden ser cambiados y compuestos para alinearse más fácilmente con los objetivos del negocio. Podemos decir entonces, que SOA no es una herramienta, no más bien es un conjunto de patrones de construcción de las nuevas aplicaciones de la empresa – más dinámicas y menos dependientes.

SOA es la evolución del modelo de programación orientado a componentes, ya que SOA agrega herramientas de computación distribuida a estas tecnologías que hemos venido utilizando por años. Podríamos decir que el cambio más grande es filosófico: en lugar de pensar en el diseño de aplicaciones individuales para resolver problemas especificos, SOA ve el software como un patrón que soporta todo el proceso del negocio. Cada elemento de un servicio es un componente que puede ser utilizado muchas veces a través de muchas funciones y procesos dentro y fuera de la empresa. Los servicios se pueden actualizar y escalar conforme sea requerido, o se pueden cambiar a una librería de terceros, sin afectar la operación del negocio – esto se da por que el componente clave de SOA no es la aplicación o el componente en uso si no más bien el contrato de uso, la interface.

La idea detrás de todo esto es que es más efectivo trabajar con servicios que con aplicaciones. Todos los componentes de una infraestructura de TI tradicional permanecen en una implementación de SOA, pero esta vez en lugar de que una aplicación soporte una funcionalidad, esta se pone disponible para todo el negocio.

Esta idea de aplicaciones como servicios alineadas a los procesos del negocio no es nueva, solamente que en esfuerzos anteriores se requería mucho esfuerzo para integrar las aplicaciones heterogéneas, además de que cada uno de estos esfuerzos tenían su propio API y su forma propietaria de comunicarse; por ejemplo CORBA y COM+.

Sin embargo, esta solución moderna que llamamos SOA, toma mucho de estos esfuerzos y de los estándares abiertos de Internet para posibilitarnos llevar a cabo esta tarea. Al día de hoy XML se ha convertido en la lengua de facto entre máquinas, lo que permite a los arquitectos ligar nuevas herramientas con aplicaciones “legacy”, y desarrollar el B2B – Business to Business - alrededor del mundo.  Esta intercomunicación no es solo entre componentes, ya que incluso se pueden describir procesos de negocio con documentos XML, utilizando lenguajes de orquestación como BPEL.

A nivel del servicio, la información se maneja como mensajes XML, definidos por un esquema XML, mientras que las interfaces de la aplicación pueden ser servicios web. XML y Servicios Web son soportardos por Java y .NET,  y estan empezando a ser soportadas por muchas más tecnologías.

En la siguiente imagen podemos ver la composición de una arquitectura orientada a servicios y la interacción de sus diversos componentes. En esta imagen faltan los elementos de infraestructura tales como el ESB, BPEL, etc.

ArquitecturaSOA
En esta imagen se puede ver que una arquitectura orientada a servicios agrega una interface de servicios ( capa lógica de servicios ) sobre los objetos de negocio y sobre las aplicaciones legacy que están alineados con los procesos del negocio. Estos objetos de negocio a su vez tienen una capa de acceso a datos la cual es la que se encarga de abstraer el acceso a las diversas fuentes de datos que utiliza la empresa.

En el siguiente post vamos a escribir acerca de lo necesario para tener SOA en la organización.

12.19.2008

Linq2XML – Filtrando en una consulta

Para continuar con el tema de linq to xml, en este post vamos a crear un ejemplo en donde se realiza una consulta a un documento XML y vamos a filtrar el contenido del XML para obtener solo los registros que cumplan con la condición que deseamos.

Para iniciar, el documento XML que vamos a utilizar es el siguiente.

<?xml version="1.0" encoding="utf-8" ?>
<
clientes>
<
cliente>
<
nombre>Juan Perez</nombre>
<
cuidad>Buenos Aires</cuidad>
<
pais>Argentina</pais>
</
cliente>
<
cliente>
<
nombre>Ernesto Jimenez</nombre>
<
cuidad>La Paz</cuidad>
<
pais>Bolivia</pais>
</
cliente>
<
cliente>
<
nombre>Ana Mora</nombre>
<
cuidad>Heredia</cuidad>
<
pais>Costa Rica</pais>
</
cliente>
<
cliente>
<
nombre>Ismael Lopez</nombre>
<
cuidad>Cuidad de Guatemala</cuidad>
<
pais>Guatemala</pais>
</
cliente>
<
cliente>
<
nombre>Diego Simon</nombre>
<
cuidad>Buenos Aires</cuidad>
<
pais>Argentina</pais>
</
cliente>
<
cliente>
<
nombre>Ismael Lopez</nombre>
<
cuidad>Cuidad de Guatemala</cuidad>
<
pais>Guatemala</pais>
</
cliente>
<
cliente>
<
nombre>Isis Benavides</nombre>
<
cuidad>Alajuela</cuidad>
<
pais>Costa Rica</pais>
</
cliente>
</
clientes>



Seguidamente vamos a crear una consulta utilizando Linq2XML en la cual vamos a seleccionar todos los clientes que tengan como país Argentina o Costa Rica. Nótese que la condición de búsqueda es compuesta, ya que debemos crear un where y un or en la condición del where. El código para llevar a cabo esta consulta es el siguiente:



static void Main( string[] args )
{
XDocument xmlDoc = XDocument.Load("Clientes.xml");
var resultado = from cliente in xmlDoc.Descendants("cliente")
where cliente.Element("pais").Value == "Argentina"
|| cliente.Element("pais").Value ==
"Costa Rica"
select new
{
Nombre = (string)cliente.Element("nombre"),
pais = (string)cliente.Element("pais")
};
foreach (var cliente in resultado)
{
Console.WriteLine(cliente.Nombre);
Console.WriteLine(cliente.pais);
Console.WriteLine("-----------------");
}
}



En general, este código es casi el mismo que utilizamos en el post anterior acerca de linq2XML, lo que lo diferencia es la condición utilizada para llevar a cabo la búsqueda. En este caso, dentro del elemento cliente utilizamos el elemento país para acceder al valor de este nodo, y lo comparamos con el nombre de los países que deseamos filtrar. Como queremos filtrar por dos países, entonces ligamos la misma condición con el símbolo (||) or en C# y procedemos a ejecutar la consulta. El resultado de la ejecución de este código se puede ver en la siguiente pantalla.



image

12.13.2008

Arquitectura de Linq

En varios post anteriores hemos venido utilizando Linq; sin embargo, no hemos visto en detalle la arquitectura de Linq para entender como es su funcionamiento. En este post, voy a  explicar como funciona Linq.

En realidad Linq funciona como una capa intermedia entre la fuente de datos y el lenguaje que se esta utilizando. Desde una perspectiva de desarrollador, es simplemente una nueva manera de consultar datos desde diversas estructuras de datos directamente en el IDE. En resumen, Linq es un lenguaje de consulta que sirve de puente entre el lenguaje que se esta utilizando y la fuente de datos de donde se quiere obtener los datos. En la siguiente figura podemos ver el flujo de Linq para llevar a cabo su funcionamiento.

image

La operación de Linq inicia en el lenguaje que utiliza el desarrollador, en nuestro caso en C#. Para escribir las consultas utilizamos los operadores de Linq y las extensiones del lenguaje. Los operadores del lenguaje se exponen a través del API de operadores de consulta estándar. Entre los operadores más comúnes tenemos:

  1. Select / SelectMany
  2. Where
  3. Sum / Min / Max / Average / Aggregate
  4. Join / GroupJoin
  5. GroupBy
  6. OrderBy / ThenBy

La extensiones del lenguaje son implementadas de manera opcional por los lenguajes que implementan Linq, esto con el fin de tratar las consultas como ciudadanos de primera clase dentro del lenguaje con que se van a escribir dichas consultas. Estas extensiones incluyen:

  1. Expresiones Lambda
  2. Inicializadores de Objetos
  3. Tipos Anónimos
  4. Sintaxis de Consulta
  5. Variables tipificadas implícitamente

Seguidamente el motor de Linq se encarga de transformar estas consultas en un conjunto de llamadas a diversos métodos para obtener los datos vía los providers de linq.

El provedor de Linq es el que permite llevar a cabo la consulta desde el lenguaje hacia la fuente de datos seleccionada. Este proveedor de datos debe de implementar las interfaces IQueryProvider e IQueryable contenidas en el espacio de nombres System.Linq. Con estas interfaces podríamos extender la funcionalidad de Linq para realizar consultas a fuentes de datos que nosotros mismos seleccionamos, por ejemplo servicios web, bases de datos no soportadas aún, etc.

La siguiente figura nos muestra la arquitectura de Linq en detalle.

image

12.12.2008

Consultas con Linq2XML

En post anteriores hemos descrito como llevar a cabo consultas de diversos tipos utilizando Linq2Objects y una lista genérica de productos como fuente de datos. En esta ocasión vamos a utilizar Linq – específicamente Linq2XML – para hacer consultas a un documento XML.

Inicialmente vamos a crear el documento XML al cual le vamos a consultar utilizando Linq2XML. El documento a utilizar es el siguiente:

<?xml version="1.0" encoding="utf-8" ?>
<
clientes>
<
cliente>
<
nombre>Juan Perez</nombre>
<
cuidad>Buenos Aires</cuidad>
<
pais>Argentina</pais>
</
cliente>
<
cliente>
<
nombre>Ernesto Jimenez</nombre>
<
cuidad>La Paz</cuidad>
<
pais>Bolivia</pais>
</
cliente>
<
cliente>
<
nombre>Ana Mora</nombre>
<
cuidad>Heredia</cuidad>
<
pais>Costa Rica</pais>
</
cliente>
<
cliente>
<
nombre>Ismael Lopez</nombre>
<
cuidad>Cuidad de Guatemala</cuidad>
<
pais>Guatemala</pais>
</
cliente>
</
clientes>



Seguidamente vamos a crear el código necesario para consultar elementos sobre este documento. Inicialmente vamos a obtener todos los clientes del documento antes presentando. El código requerido para llevar a cabo esta consulta es el siguiente.



static void Main( string[] args )
{
XDocument xmlDoc = XDocument.Load("Clientes.xml");
var resultado = from cliente in xmlDoc.Descendants("cliente")
select new
{
Nombre = (string)cliente.Element("nombre"),
pais = (string)cliente.Element("pais")
};
foreach (var cliente in resultado)
{
Console.WriteLine(cliente.Nombre);
Console.WriteLine(cliente.pais);
Console.WriteLine("-----------------");
}
}



En este código simplemente cargamos el documento xml en una variable de tipo XDocument, seguidamente seleccionamos todos los descendientes del nodo raíz que en este caso es cliente, y luego creamos objetos anónimos con el nombre y el país del cliente que estamos consultando.



El resultado al ejecutar esta consulta se ve en la siguiente pantalla:



image



En los post próximos vamos a ver como ampliar el uso de Linq2XML en lo que se refiere a consultas de diversos tipos.

12.02.2008

Arquitecturas N-Layer – Ventajas y desventajas

En el post pasado, escribí acerca de las ventajas y las desventajas de utilizar una arquitectura n-tier, en este post voy a abarcar las ventajas y desventajas de utilizar una arquitectura n-layer desde mi punto de vista.

Dado que una arquitectura n-layer es una forma lógica de distribuir la aplicación, este tiene sus mayores ventajas en lo que respecta al desarrollo de la aplicación, su mantenimiento y su escalabilidad. Las principales ventajas de desarrollar una aplicación n-layer son:

  • Flexibilidad: Permite que los componentes sean modificados para llevar a cabo sus tareas sin necesidad de recompilar toda la aplicación – resguardando siempre el contrato definido para la operación. Además permite utilizar estos componentes en diversos tipos de aplicaciones y no exclusivamente para la aplicación que fueron diseñados.
  • Mantenibilidad: Facilita la tarea de modificar un componente para corregir errores, mejorar el desempeño, agregar atributos, o adaptarlos a un ambiente cambiante.
  • Reutilización: todos los componentes pueden ser utilizados desde otros componentes o desde otros sistemas. Incluso si los componentes de negocio son consumidos a través de servicios, esos servicios pueden ser reutilizados por otros sistemas internos o externos.
  • Escalabilidad: Facilita que un componente se pueda adaptar al cambio. Cuando el sistema crece en funcionalidad pero esta está definida por diferentes clientes, se pueden crear nuevos componentes sobre los componentes base para poder especializar más las capacidades de un componente específico para un cliente en específico.

La principal desventaja que yo encuentro con las aplicaciones n-layer, es que al inicio del desarrollo se consume mucho tiempo creando los componentes “core” de los sistemas; y las empresas o departamentos de TI por lo generar quieren mostrar a sus clientes – internos o externos - aspectos tangibles del sistema que se está desarrollando. Por supuesto, esta desventaja se desvanece con el paso del tiempo y con el avance en el desarrollo, porque una vez creado el “core” del sistema, el avance es impresionantemente rápido.

11.30.2008

Arquitecturas n-tier – Ventajas y Desventajas

Ahora que ya aclaramos las diferencias entre una arquitectura n-layer y una arquitectura n-tier en un post anterior, surgen dudas respecto a las ventajas y las desventajas de cada una de ellas.  Es precisamente respecto a ese tema lo que vamos a escribir en este post. Inicialmente nos vamos a enfocar en la arquitectura física ( n-tier ) y en post posteriores vamos a escribir acerca de las arquitecturas lógicas ( n-layer ).

Ventajas y Desventajas de las arquitecturas n-tier

Desde el punto de vista físico, la duda principal nace al decidir si utilizamos una arquitectura de 2 capas (2-tier) o una arquitectura de 3 capas(3-tier). Básicamente, una arquitectura 2 capas es una arquitectura donde el UI y los componentes de negocio o los componentes de negocio y el repositorio de datos residen en una misma capa física – Por ejemplo, aplicaciones web que tienen los componentes de negocio en el web server. Las aplicaciones 3 capas ( 3-tier ) dividen cada uno de estos componentes en ubicaciones físicas diferentes – Por ejemplo, cuando se utiliza un servidor de aplicaciones para hostear los componentes de negocio y otro servidor (web server) para hostear las páginas del sitio web.

Las desventajas principales de una arquitectura 3-tier sobre una arquitectura 2-tier son el costo y la complejidad. El costo aumenta por que se requiere un servidor adicional para hospedar los componentes desde donde se va a consumir toda la lógica de negocios, lo que trae consigo ítems adicionales que se deben tomar en cuenta tales como costo de licencias, costo mantenimiento de servidor, etc. La complejidad aumenta por que los componentes viven en su propio “ecosistema”, con lo cual se crea un punto extra de falla; es decir, tengo un servidor más que mantener y monitorear. Además, se va a crear un “brinco” adicional cada vez que se hace una llamada a los componentes de negocio que residen en este servidor de aplicaciones, lo que me lleva a tener una respuesta más lenta ( a diferencia de una arquitectura 2 capas donde los componentes residen en el mismo servidor donde reside la aplicacion ).

Las ventajas de una arquitectura 3 tier respecto a una arquitectura 2-tier son básicamente las siguientes:

Seguridad: Al agregarse un servidor de aplicaciones se agrega un nivel extra de seguridad, ya que existen procesos de autenticación y autorización en el servidor de aplicaciones que se agregan a los procesos ya existentes en los otros servidores, – base de datos y servidor Web -con lo que el hackear el servidor de aplicaciones, no da acceso de facto al servidor de base de datos.

Escalabilidad: Al utilizarse un servidor de aplicaciones se pueden crear pools de conexiones hacia la base de datos con lo cual se reutilizan las conexiones existentes para múltiples usuarios. Además, si mi aplicación es accedida por una cantidad de usuarios superior a la esperada y su rendimiento espera a bajar, podemos crear balanceo en el servidor de aplicaciones para que el tiempo de atención y respuesta sea más rápido.

11.23.2008

Linq – Join sobre Múltiples Listas Genéricas de Objetos

En el post anterior, hicimos una consulta a una lista de productos utilizando Linq – Linq2Objects. Sin embargo, es normal buscar objetos desde múltiples fuentes de datos. En Linq tenemos la clausula join que nos permite unir múltiples fuentes de datos y no solamente desde base de datos.

Supongamos que tenemos una lista de clientes y un plan de millas de una aerolínea y tenemos que buscar todos los clientes que pertenecen a un plan específico definido por la aerolínea.

El primer paso, es crear la clase cliente y la clase plan de millas. El código de ambas clases se presenta a continuación.

public class Cliente
{
public int Id { get; set; }
public string Nombre { get; set; }
public string PaisResidencia { get; set; }
public int IdPlanDeMillas { get; set; }
}


public class PlanDeMillas
{
public int Id { get; set; }
public string Plan { get; set; }
public bool VencenMillas { get; set; }
}


Como podemos ver, el plan de millas esta asociado con el cliente a través del Id del plan de millas dentro de la clase cliente. Seguidamente mostramos dos métodos en donde se inicializan dos listas, una de clientes y otras de millas. En la lista de clientes se indica a cual plan de millas pertenece el cliente.



private static List<Cliente> GetListaClientes( )
{
return new List<Cliente>( )
{
new Cliente ()
{
Id = 0,
IdPlanDeMillas = 0,
Nombre = "Juan Romero",
PaisResidencia = "Guatemala"
},
new Cliente ()
{
Id = 1,
IdPlanDeMillas = 1,
Nombre = "Carlos Jimenez",
PaisResidencia = "Uruguay"
},
new Cliente ()
{
Id = 2,
IdPlanDeMillas = 2,
Nombre = "Elisa Perez",
PaisResidencia = "Guatemala"
},
new Cliente ()
{
Id = 3,
IdPlanDeMillas = 2,
Nombre = "Sebastian Ortuño",
PaisResidencia = "Uruguay"
},
new Cliente ()
{
Id = 4,
IdPlanDeMillas = 0,
Nombre = "Luis Barquero",
PaisResidencia = "Costa Rica"
},
new Cliente ()
{
Id = 5,
IdPlanDeMillas = 1,
Nombre = "Ana Rodriguez",
PaisResidencia = "Costa Rica"
},
};
}



private static List<PlanDeMillas> GetListaPlanes( )
{
return new List<PlanDeMillas>( )
{
new PlanDeMillas ()
{
Id = 0,
Plan = "Estándar",
VencenMillas = true
},
new PlanDeMillas ()
{
Id = 1,
Plan = "Oro",
VencenMillas = false
},
new PlanDeMillas ()
{
Id = 2,
Plan = "Platino",
VencenMillas = false
}
};
}


Por último, creamos la sentencia Linq para hacer un join de ambas colecciones a través del Id del Plan de Millas. El código completo con la llamada a la inicialización de las listas, la consulta Linq, y su despliegue en la consola se muestra a continuación.



 



List<Cliente> listaClientes = GetListaClientes( );
List<PlanDeMillas> listaPlanes = GetListaPlanes( );

var resultado = from cliente in listaClientes
join plan in listaPlanes
on
cliente.IdPlanDeMillas equals plan.Id
select new
{
cliente.Nombre,
cliente.PaisResidencia,
plan.Plan,
plan.VencenMillas
};

Console.WriteLine("--------------------------------------");
Console.WriteLine("Reporte de plan de millas por usuario");
Console.WriteLine("--------------------------------------");
foreach (var clientePlan in resultado)
{
Console.WriteLine("Cliente: {0}", clientePlan.Nombre);
Console.WriteLine("Tipo de Plan: {0}", clientePlan.Plan);
Console.WriteLine("Vencen las millas: {0}", clientePlan.VencenMillas);
Console.WriteLine("--------------------------------------");
}



Al analizar la consulta linq en el código anterior, podemos identificar las siguientes características de la consulta:





  1. El uso del join para hacer la consulta. En este caso, estamos llevando a cabo esta operación en base al Id del plan de millas en la clase PlanDeMillas y el Id del plan incluido en el cliente.




  2. La selección de un objeto customizado como parte de la consulta. En este caso, deseamos una lista de objetos de un tipo que no tenemos definido, por lo tanto, al crear el nuevo objeto que se va a agregar a la lista de forma iterativa no indicamos el tipo del objeto que vamos a almacenar en la lista, si no que simplemente inicializamos un tipo anónimo. En este caso, el compilador genera un nombre único para el nuevo tipo.




  3. El uso del tipo var. Dado que la clausula select retorna un tipo anónimo, no se puede definir un tipo explícito tal como IEnumerable<T> para contener el resultado de la consulta en la lista. En este caso el compilador infiere el tipo de la variable a partir de su inicialización, y declara la lista en base a este. Esta característica en C# 3.0 y superior se conoce como variables locales tipadas implícitamente.




El resultado al ejecutar la consulta anterior se muestra en la siguiente pantalla.



image

11.20.2008

Usando Linq para Hacer Búsquedas de Objetos en Listas Genéricas

En post pasados, vimos como realizar búsquedas de objetos en una lista genérica utilizando distintos métodos de la clase List. En este post, vamos a utilizar Linq para buscar objetos dentro de una lista genérica.

En primera instancia, vamos a utilizar la clase producto que hemos venido utilizando en post anteriores. Vamos a inicializar una lista de productos de la misma manera que lo hicimos en el post anterior:

List<Producto> listaProductos = new List<Producto>( )
{
new Producto ()
{
Id = 09,
Nombre = "Impresora Canon MP140",
PaisDeOrigen = "Japón",
Precio = 50
},
new Producto ()
{
Id = 15,
Nombre = "Age of Empires III",
PaisDeOrigen = "USA",
Precio = 29.99
},
new Producto ()
{
Id = 12,
Nombre = "Laptop Dell Vostro",
PaisDeOrigen = "USA",
Precio = 999
},
new Producto ()
{
Id = 33,
Nombre = "IPod Nano 2",
PaisDeOrigen = "USA",
Precio = 199.99
},
new Producto ()
{
Id = 26,
Nombre = "Audífonos JVC",
PaisDeOrigen = "Holanda",
Precio = 39.99
}
};



Seguidamente, vamos a crear una consulta utilizando LinqToObjects para buscar todos los objetos que tienen su país de origen igual a “USA”. El siguiente código nos muestra como hacerlo.



IEnumerable<Producto> resultado =
from producto in listaProductos
where producto.PaisDeOrigen ==
"USA"
select producto;


Console.WriteLine("----------------------------");
Console.WriteLine("Productos Originarios de USA");
foreach (Producto producto in resultado)
{
Console.WriteLine("----------------------------");
Console.WriteLine("Nombre: {0}\nPrecio: {1}",
producto.Nombre, producto.Precio);
}


Como podemos ver en el código anterior, Linq tiene una sintaxis muy similar a la de SQL Server, solamente que Linq además de poder ser utilizado en SQLServer (aunque parece que se va a descontinuar), es aplicable a Objetos, Xml, DataSet, EF y a los Data Services.



En este ejemplo, para retornar la lista de productos que tienen su país de origen como “USA”, se debe de asignar el resultado de la consulta a una lista genérica de productos, esta lista esta definida por IEnumerable<Producto>. A través de la claúsula from, estamos definiendo el origen de los datos, permitiendole a Linq iterar sobre cada producto para identificar las variables que cumplen con el criterio de selección a través de la palabra reservada from. Por último, se indica que se quiere proyectar ( seleccionar ) de la consulta realizada. En este caso escojimos seleccionar el producto como tal, pero como veremos en post posteriores, podemos utilizar tipos anónimos para seleccionar campos de un objeto, o de varios objetos utilizados como repositorio de datos.



El resultado al ejecutar la consulta anterior se puede ver en la siguiente imagen.



image

11.15.2008

Inicializando Colecciones con la Inicialización Automática de Objetos en C# 3

En el post anterior vimos como inicializar objetos utilizando sus propiedades y no el constructor del objeto. En este post vamos a continuar con este tema, mostrando como se inicializa una lista genérica de objetos a través de sus propiedades.

Igualmente, vamos a utilizar la clase producto que utilizamos en el post anterior. En este caso, no vamos a crear instancias de producto y luego las vamos a agregar a la lista, si no que vamos a inicializar los objetos y la lista utilizando la inicialización automática a través de propiedades en C#. En el siguiente bloque de código se muestra como llevar a cabo esta inicialización.

List<Producto> listaProductos = new List<Producto>( )
{
new Producto ()
{
Id = 0,
Nombre = "Impresora Canon MP140",
PaisDeOrigen = "Japón",
Precio = 50
},
new Producto ()
{
Id = 1,
Nombre = "Age of Empires III",
PaisDeOrigen = "USA",
Precio = 29.99
},
new Producto ()
{
Id = 2,
Nombre = "Laptop Dell Vostro",
PaisDeOrigen = "USA",
Precio = 999
}
};


Como podemos ver en el código anterior, podemos inicializar la lista con instancias de objetos que se inicializan automáticamente con sus propiedades a la hora de agregarse a la lista. Ahora podemos recorrer la lista y visualizar su contenido como lo haríamos con cualquier otra lista genérica.



 



foreach (Producto producto in listaProductos)
{
Console.WriteLine("-------------------------");
Console.WriteLine("Id Producto: {0}", producto.Id);
Console.WriteLine("Nombre Producto: {0}", producto.Nombre);
Console.WriteLine("País Producto: {0}", producto.PaisDeOrigen);
Console.WriteLine("Precio Producto: {0}", producto.Precio);
}


El resultado al ejecutar el código anterior desde una aplicación de consola es el siguiente:



image

11.12.2008

Inicializadores de Objetos en C# 3.0

Una de las nuevas caracterísiticas en C# 3.0 es la inicialización de objetos. En versiones anteriores del lenguaje C#, para inicializar un objeto a la hora de su construcción, se debían crear constructores con los parámetros requeridos, los cuales llevaban a cabo la inicialización del objeto que esta siendo instanciado. A partir de la versión 3.0 de C#, se pueden inicializar objetos tanto a través de constructores, como a través de inicializadores automáticos.

¿En que consisten estos inicializadores? Los inicializadores, son una manera simple de inicializar objetos a través de sus propiedades. Para comprender mejor esta característica veamos el siguiente ejemplo.

Vamos a trabajar con la clase producto definida en el post pasado. Vamos a crear una instancia de esta clase utilizando los inicializadores de objetos presentes en C# 3.0 o superior.

Como podemos ver en la siguiente imagen, cuando estamos inicializando la instancia de la clase, VS 2008 nos permite ver las propiedades existentes dentro de la clase para llevar a cabo la inicialización a través del intellisense.

image

El código completo para inicializar la instancia de prod es el siguiente.

static void Main( string[] args )
{
Producto prod = new Producto( )
{
Id = 0,
Nombre = "Impresora Canon MP140",
PaisDeOrigen = "Japón",
Precio = 50
};
Console.WriteLine("Producto: {0}", prod.Nombre);
}


El resultado de la ejecución del código anterior es el siguiente



image



Igualmente, podemos inicializar objetos dentro de otros objetos de la misma manera que hicimos la inicialización anterior.



Supongamos que existe una clase DetalleDeFactura que contiene un producto asociado y la cantidad del producto que se agregó al detalle. El código de esta clase es el que se ve a continuación:



public class DetalleDeFactura
{
public int Id { get; set; }
public int CantidadDeProducto { get; set; }
public Producto ProductoSeleccionado { get; set; }
}



Para inicializar la clase DetalleFactura utilizamos el código siguiente:



 



static void Main( string[] args )
{
DetalleDeFactura detalle = new DetalleDeFactura( )
{
Id = 1,
CantidadDeProducto = 3,
ProductoSeleccionado = new Producto( )
{
Id = 0,
Nombre = "Impresora Canon MP140",
PaisDeOrigen = "Japón",
Precio = 50
}
};

Console.WriteLine("Detalle: {0}", detalle.Id);
Console.WriteLine("Producto: {0}", detalle.ProductoSeleccionado.Nombre);
Console.WriteLine("Cantidad: {0}", detalle.CantidadDeProducto);
}



El resultado al ejecutar esta consulta es:



image



Como podemos ver, esta forma de inicializar objetos es muy intuitiva y “limpia” a la hora de digitar el código requerido para iniciar el objeto requerido. Además, esto nos permite utilizar expresiones Lambda en Linq como veremos en posts posteriores.

11.08.2008

Propiedades Automáticas en C# 3

Una de las nuevas características en C# 3 son las propiedades automáticas. Esta característica consiste simplemente en tener la posibilidad de declarar las propiedades requeridas, con el get y el set vacíos. El compilador se encarga de generar en código intermedio (MSIL) los atributos requeridos para cada una de las propiedades automáticas. Para entender mejor esta característica, veamos un ejemplo.

Supongamos que deseamos tener una clase Producto con una serie de atributos como el Id, el nombre, el precio y el país de origen. Anteriormente, para llevar a cabo esta tarea, debiamos definir los atributos y seguidamente crear las propiedades de estos atributos. Con esta nueva característica, simplemente tenemos que crear las propiedades vacías tal y como se ve en la siguiente definición de la clase.

public class Producto
{
public int Id { get; set; }
public string Nombre { get; set; }
public double Precio { get; set; }
public string PaisDeOrigen { get; set; }

public override string ToString( )
{
return string.Format("Id: {0}, Producto: {1}, Precio: {2}, Pais: {3}", Id, Nombre, Precio.ToString( ), PaisDeOrigen);
}
}



Para utilizar la clase anterior, simplemente se crea una instancia de la clase producto, y se acceden sus propiedades de la manera que normalmente lo haríamos si los atributos de la clase hubieran sido definidos manualmente.



static void Main( string[] args )
{

Producto miProducto = new Producto ();
miProducto.Id = 0;
miProducto.Nombre = "Audífonos JVC Super bass";
miProducto.PaisDeOrigen = "Holanda";
miProducto.Precio = 49.99;
Console.WriteLine(miProducto);
}



El resultado al ejecutar este código se ve en la siguiente figura:



image



En este caso, para imprimir la información del producto, cuando se llama al método estático WriteLine de la clase Console, se esta llamando al método que acabamos de sobre escribir ToString de la clases Producto. Este es un comportamiento que se da por defecto cuando se manda a escribir algún objeto.



Ahora, ¿qué obtenemos al utilizar las propiedades dinámicas? Básicamente nos liberamos de la necesidad de declarar variables privadas y su accesor get y set, osea la propiedad. Aunque podemos usar alguna herramienta de refactoring para encapsular los campos, si no se requieren reglas de validación de negocio dentro de las propiedades, el código es más legible utilizando propiedades automáticas.

11.06.2008

¿Esta Linq To SQL Muerto?

En muchas ocasiones, surge la pregunta casi obligada por parte de la gente acerca de si Linq To SQL es una buena opción a utilizar en el desarrollo de aplicaciones. Se ha escrito mucho acerca de cuál es el rol del LinqToSQL y si realmente es un ORM o no lo es. Igualmente, existen muchos debates acerca de cual es la mejor opción para utilizar LinqToSQL en una arquitectura n capas.

Seguidamente, con la aparición del entity framework se generó más confusión, dado que el entity framework si es un ORM como tal; dejando entonces la pregunta: ¿ Qué rol juega LinqToSQL en el desarrollo de aplicaciones ? ¿ Podrán los dos convivir ?

Todo esto por supuesto, tomando en cuenta que Linq no es solamente LinqToSQL si no más bien un lenguaje que en este momento cuenta con un conjunto de fuentes de datos en donde se puede utilizar. Además de LinqToSQL se incluyen LinqToXML, LinqToObjects, LinqToDataSet, LinqToDataServices y LinqToEntities( EntityFramework )

En días reciente, el grupo de ADO.NET hizo un anuncio que parece va a aclarar un poco más las cosas. Al parecer, la idea del grupo que desarrolla Linq es favorecer  y mejorar el entity framework y empezar a matar Linq to SQL. David Hayen es un poco más directo en sus apreciaciones sobre el futuro de LinqToSQL. Saquen sus conclusiones.

11.02.2008

Buscando un Objeto en una Lista Genérica Utilizando el Método Contains

Una de las tareas más comúnes cuando estamos desarrollando una aplicación que utiliza una lista de tipo Generic, es el identificar si en la lista existe un objeto determinado. Para llevar a cabo esta labor, existe un método en la clase List<T> llamado Contains que hace precisamente esto. Este método determina si los objetos son iguales utilizando el comparador de igualdad EqualityComparer.Default para el tipo T, el tipo de los elementos en la lista. Este método lleva a cabo una búsqueda lineal, por lo que esta es una operación O(n), donde n = todal de elementos en la lista.

Este comparador determina a través de su propiedad Default si el tipo T implementa la interface genérica System.IEquatable; si es así, retorna un EqualityComparer que utiliza esa implementación. Si no lo implementa, retorna el EqualityComparer que utiliza Object.Equals y Object.GetHasCode de T. En otras palabras, si tenemos implementado un método para comparar dentro de nuestra clase T, se utiliza este método, de lo contrario, se utiliza el método por defecto Object.Equals. El siguiente ejemplo muestra como se implementa este método, y como se busca un objeto en una lista genérica utilizando el método Contains.

Primeramente, vamos a utilizar la clase persona utilizada en ejemplos anteriores, pero en esta oportunidad le vamos a agregar la implementación de IEquatable.

public class Persona : IEquatable<Persona>
{
private int m_Id;
private string m_Nombre;
private string m_Apellido1;
private string m_Apellido2;
private string m_Pais;


Seguidamente vamos a implementar el método Equals de la interfase IEquatable. En este método debemos definir como vamos a llevar a cabo la comparación entre la instancia actual, y la que viene por parámetro. En nuestro ejemplo, vamos a decir que un objeto es igual a otro si el nombre de la persona de ambos objetos es el mismo, y si el Id de los objetos es el mismo. La implementación de este método es la siguiente:



#region IEquatable<Persona> Members

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

#endregion



Para probar nuestro método de comparación, vamos a crear una lista genérica con 6 personas, tal y como lo hicimos en los ejemplos anteriores.



List<Persona> listaPersonas = new List<Persona>( );
Persona p1 = new Persona(1, "Manuel", "Perez", "Ruiz", "Mexico");
Persona p2 = new Persona(2, "Arnoldo", "Rojas", "Gomez", "Panama");
Persona p3 = new Persona(3, "Juan", "Ramos", "De la O", "España");
Persona p4 = new Persona(4, "Miguel", "Cortez", "Valerio", "Costa Rica");
Persona p5 = new Persona(5, "Andres", "Perez", "Fonseca", "Mexico");
Persona p6 = new Persona(6, "Antonio", "Aleman", "Rodriguez", "Mexico");
listaPersonas.Add(p1);
listaPersonas.Add(p2);
listaPersonas.Add(p3);
listaPersonas.Add(p4);
listaPersonas.Add(p5);
listaPersonas.Add(p6);



Por último, vamos a crear una instancia de persona y la vamos a incializar con los datos de la persona p2, y vamos a buscar en la lista si esta nueva instancia que llamaremos personaABuscar contiene los datos de una persona que si existe dentro de la lista que acabamos de crear - listaPersonas. Esta búsqueda la haremos utilizando el método Contains, el cual como mencionamos anteriormente, utiliza el método Equals implementado en la clase Persona.



Persona personaABuscar = new Persona(2, "Arnoldo", "Rojas", "Gomez", "Panama");
if (listaPersonas.Contains(personaABuscar))
Console.WriteLine("{0} {1} existe en la lista",
personaABuscar.Nombre, personaABuscar.Apellido1);
else
Console.WriteLine("{0} {1} existe NO en la lista",
personaABuscar.Nombre, personaABuscar.Apellido1);



El resultado al ejecutar el código anterior – este proyecto al igual que los anteriores es un proyecto de consola – se ve en la siguiente imagen.



image

10.21.2008

¿Arquitectura n-Tier o Arquitectura n-Layer?

Al parecer existe una confusión respecto al término aplicación n-capas cuando este se lleva al idioma español. El problema principal es que en inglés se manejan dos conceptos a nivel de arquitectura:

  • Aplicaciones n-Tier
  • Aplicaciones n-Layer

Ambos términos significan “de n capas"; pero existe una gran diferencia respecto al significado de cada uno de ellos. Una arquitectura n-Tier se refiere a la distribución física de las capas, es decir donde corre el código y los procesos. Una arquitectura n-Layer se refiere a la distribución lógica de las capas, es decir, como esta estructurado el código.

En la siguiente figura podemos ver una aplicación n-tier – una aplicación web - que contiene 3 capas, una capa en el cliente, otra en el servidor IIS, y otra en la base de datos; es decir, el navegador, el servidor Web y el servidor de bases de datos corren en diferentes máquinas.

Ejemplo Arquitectura n-Tier

Por otra parte, una arquitectura n-Layer define simplemente como se organiza el código. Normalmente incluye una capa de presentación, una capa de negocios, una capa de acceso a datos, una capa de entidades de negocio y una capa de datos – repositorio de datos. El hecho de que se dividan las capas para organizar el código, no significa que las capas obligatoriamente deban corren en diferentes máquinas o que deben estrictamente correr en una sola máquina o en un único proceso.

La siguiente figura detalla una arquitectura n-Layer básica.

Arquitectura N-Layer

Como podemos ver en la figura, en una arquitectura n-layer las capas solamente interactúan con sus capas adyacentes lo que permite abstraer funcionalidades de las capas superiores e inferiores. Por ejemplo, la capa de presentación no se da cuenta que tipo de base de datos o que repositorio de datos se utiliza por que esta solamente se comunica con la capa de negocios, y el repositorio de datos no se da cuenta en donde se esta utilizando o desplegando la información ya que este interactúa con la capa de acceso a datos.

En los post siguientes vamos a hablar el por que es importante dividir las aplicaciones en capas, y vamos a profundizar en las arquitecturas n-Layer.

10.18.2008

Buscando Elementos dentro de una Lista Generica - List.FindIndex

En el post anterior, trabajamos con el método List<T>.FindAll, el cual se encarga de obtener todos los elementos que concuerdan con un predicado definido por el usuario para comparar. En esta oportunidad vamos a trabajar con el método FindIndex de una lista genérica.

De acuerdo al msdn, el método FindIndex busca un elemento que cumpla con las condiciones especificadas por un predicado, y retorna el índice en la lista de la primera ocurrencia. Este índice inicia en 0 para el primer elemento y termina en el largo de la lista – 1 para el último elemento.

En este ejemplo vamos a buscar a la primera persona que vive en Costa Rica, y para tal fin vamos a utilizar la clase persona utilizada en el post anterior, y vamos a utilizar la lista cargada con los mismos datos del mismo post. Es importante recordar que esta aplicación de ejemplo, es una aplicación de consola.

Para iniciar, tenemos que crear un método que nos devuelva verdadero si la persona que viene por parámetro vive en Costa Rica o no. Este método será utilizado como predicado para buscar el elemento deseado dentro de la lista. Además, este método se va a invocar una vez por cada elemento dentro de la lista hasta que se encuentre el elemento buscado o hasta que finalice la lista. El método se muestra a continuación:

static bool viveEnCostaRica( Persona persona )
{
if (persona.Pais == "Costa Rica")
return true;
return false;
}


El siguiente método, es un método que busca el primer elemento que contenga como país “Costa Rica”, por lo tanto invoca el método FindIndex una vez con el método anterior como predicado.



static int IndicePrimeraPersonaQueViveEnCostaRica( List<Persona> listaPersonas )
{
int indice = listaPersonas.FindIndex(viveEnCostaRica);
return indice;
}


Por último, invocamos el método IndicePrimeraPersonaQueViveEnCostaRica y desplegamos en la consola el índice de la primera persona encontrada. Se debe destacar que si no se encuentra ninguna persona que cumpla con la condición establecida, el índice retornado es –1.



Console.WriteLine("Índice de la Primera Persona Encontrada de Costa Rica");
Console.WriteLine("------------------------------");
Console.WriteLine("Ínidice: {0} ", IndicePrimeraPersonaQueViveEnCostaRica(listaPersonas));



El resultado se puede ver en la siguiente figura.



image

10.12.2008

Buscando Elementos dentro de una Lista Generica - List.FindAll(Predicado)

En el post anterior, explicamos y hicimos un pequeño ejemplo acerca de como buscar un elemento dentro de una lista genérica, utilizando el método List<T>.Find. En esta oportunidad vamos a trabajar con el método FindAll de una lista genérica.

De acuerdo al msdn, el método FindAll obtiene todos los elementos que concuerden con las condiciones definidas por el predicado específico. Esto quiere decir que a diferencia del método Find que devuelve el primer objeto que cumple con el predicado, este método devuelve la lista de todos los objetos que cumplen con el predicado.

En este ejemplo vamos a buscar todas las personas que viven en México, y para tal fin vamos a utilizar la clase persona utilizada en el post anterior, y vamos a utilizar la lista cargada con los mismos datos del mismo post. Es importante recordar que esta aplicación de ejemplo, es una aplicación de consola.

El método para buscar las personas que viven en México a partir de una lista de personas es el siguiente.

image

Este método recibe la lista de objetos de instancia de persona que se va a recorrer para buscar solamente las que viven en México. El predicado para utilizar el método FindAll, es un handler a la función PersonaDeMexico, que se encarga de identificar si el objeto que se compara tiene como país México dentro de sus valores en la propiedad Pais. Hay que notar que al igual que el método Find, FindAll solo requiere una llamada al método, pero internamente se recorre toda la lista comparando todos los objetos que hay dentro de ella a través del método especificado en el predicado, en este caso PersonaDeMexico. FindAll devuelve todos los objetos que cumplieron de forma positiva en el predicado y los retorna al método que lo invoca. El método PersonaDeMexico que se utiliza en el predicado se presenta a continuación.

image

El método PersonaDeMexico, solamente compara la propiedad país contra el valor “Mexico” y retorna verdadero si la condición de cumple.

Para invocar el método BuscarPersonasDeMexico, se procede tal y como lo muestra el siguiente código.

image

 

 

 

 

 

El resultado al ejecutar el programa anterior es el siguiente:

image

10.09.2008

Buscando Elementos dentro de una Lista Generica - List<T>.Find(Predicado)

Es muy común tener la necesidad de buscar objetos en una colección basado en un criterio de búsqueda. Normalmente en ciertos momentos del desarrollo de una aplicación que utilice colecciones de objetos – en especial objetos de negocio - nos vamos a enfrentar a la necesidad de llevar a cabo tareas como por ejemplo: necesito obtener todos los objetos dentro de la lista que cumplen con el criterio X, necesito todos los objetos que su índice es mayor que Y, etc.

Para llevar a cabo esta tarea de una manera simple, en .NET la clase List<> tiene una serie de métodos que permiten realizar búsqueda sobre listas de objetos utilizando predicados especificos en la llamada.

Vamos a utilizar el método Find para buscar el primer objeto que cumpla con un predicado que nosotros mismos vamos a especificar a través de un método. Vamos a usar como base la clase Persona que vemos en la siguiente figura.

Clase_Persona

Seguidamtente vamos a inicializar una lista de personas la cual utilizaremos como referencia durante todos los ejemplos que vamos a desarrollar:

InicializarLista

El método Find de acuerdo al msdn permite buscar un elemento que concuerde con las condiciones definidas por un predicado específico, y retorna el primer objeto con cumpla con esta condición en la lista. Por ejemplo, supongamos que queremos la primera persona que tenga como nombre Juan y su primer apellido sea Ramos. El primer paso es crear un método para buscar la persona deseada. En este caso, vamos a buscar a Juan Ramos y vamos a retornar verdadero cuando lo encontramos y falso cuando no es el objeto que buscamos – En este caso la condición se encuentra digitada de manera directa, pero esta podría hacer referencia a una propiedad, a un campo de texto en una interface gráfica, etc.

CompararPersona

Seguidamente, vamos a crear un método que invoca el método find a travez del predicado definido, el cual en este caso será el método CompararPersona. Nótese que este método se “invoca” solamente una vez desde la lista, aunque internamente, el método se llama una vez por objeto contenido en la lista hasta que se termine la lista o se encuentre el objeto.

 BuscarPersona

Ahora, desde el método main, invocamos el método BuscarPersona e imprimos el pais donde reside la persona a buscar.

FindBuscarPersona

Y listo, el resultado se puede ver en la siguiente figura.

image

9.29.2008

Paging using a CheckBoxList, a PagedDataSource and the Ajax.NET

Recently, I had the need for doing paging using a check list box. Besides, I need to use Ajax.Net for making the paging work faster. So I decided to blog on how to do this task.

First web have to add the Ajax Script Manager and the Ajax Update panel to the page, so we can drag our list control inside it and page using the ajax functionality.

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
        
        </ContentTemplate>
        </asp:UpdatePanel>

    </div>

Then we add the list and the next and previous controls for moving using the paging functionality.

<ContentTemplate>

        <asp:CheckBoxList ID="CheckBoxList1" runat="server">
        </asp:CheckBoxList>
        <div>
            <asp:LinkButton ID="lnkPrev" runat="server"  onclick="lnkPrev_Click"><<</asp:LinkButton> ||
            <asp:LinkButton ID="lnkNext" runat="server" onclick="lnkNext_Click">>></asp:LinkButton>

        </div>

</ContentTemplate>

Then we need to add the code functionality to make the complete code work. First, we have to create a function that does the Binding for the list. Here is where the PagedDataSource object is used. Instead of doing the bind directly from the collection to the list, we have to bind it to the PagedDataSource object, this allows all the paging functionality for the List. Besides, we need to set the page index, this will be doing by the use of a session variable.Then we just bind the list to the PagedDataSource object like follows.

private void DoPaging( )
{
    List<int> sampleData = new List<int>();
    for (int i = 0; i < 150000; i++)
    {
        sampleData.Add(i);
    }

    PagedDataSource pagingSource = new PagedDataSource( );
    pagingSource.DataSource = sampleData;
    pagingSource.AllowPaging = true;
    pagingSource.PageSize = 10;
    pagingSource.CurrentPageIndex = (int) Session ["PageNumber"];

    CheckBoxList1.DataSource = pagingSource;
    CheckBoxList1.DataBind( );

}

We have to initialize the page doing the call for the method explained before and we also set the Page number session variable to the first page since we are initializing the form.

protected void Page_Load(object sender, EventArgs e)
{
    if ( !Page.IsPostBack)
    {
        Session["PageNumber"] = 0;
        DoPaging();
    }
}

Then we have to create the next and the previous events handlers for the link buttons we placed for navigation.

protected void lnkNext_Click( object sender, EventArgs e )
{
    int currentIndex = (int) Session["PageNumber"];
    Session["PageNumber"] = currentIndex + 1;
    DoPaging();
}
protected void lnkPrev_Click( object sender, EventArgs e )
{
    int currentIndex = (int)Session["PageNumber"];
    Session["PageNumber"] = currentIndex - 1;
    DoPaging();
}

And that’s all. We run the demo and we have a CheckListBox with paging and with ajax.

It is important to point that we are initializing the paging using a simple int generic that fills with 150000 items. If we are going to the database, we have to use some other method for not keep going to the database each time we click next or previous, for example, storing your entity object inside a session variable or Serializing your object in the server side.

2.04.2008

Conectar un servicio Web desde un emulador de Smartphone

En días pasados, tuve la oportunidad de llevar a cabo una simple aplicación que consumía un servicio web desde una aplicación móvil desde un emulador de un Smartphone desde Windows Vista. Llevar a cabo esta tarea parece simple, ya que uno tiende a pensar que simplemente lo que requiero es desarrollar la aplicación móvil, agregar la referencia web y listo…consumirla. Pero como siempre, hay condiciones que se dan y no se tienen en cuenta a la hora de desarrollar este tipo de aplicación. Por esta razón, me doy a la tarea de documentar todos los pasos que tuve que llevar a cabo para lograr que la aplicación funcionara tal y como se esperaba.
Para conectar un emulador a un servicio Web se deben de tomar las siguientes consideraciones:
1. El primer paso es desarrollar el servicio web y probarlo desde el internet explorer para validar su funcionamiento correcto. Luego se instala el servicio Web en el IIS. Esto para permitir a la aplicación web referenciar el servicio desde el servidor del sistema operativo y no desde el servidor web que trae para desarrollo Visual Studio .NET.
2. El segundo paso es agregar la referencia web del servicio recién instalado y que se desea consumir en el proyecto móvil. En este paso es importante no usar la referencia del proyecto de servicio web que reside en la misma solución, ya que esto conlleva a que el debuguer de la aplicación utilice el Web server que trae .NET por defecto para hacer deploy del servicio web recién desarrollado; y este servidor web, bloquea todas las conexiones externas que se le hagan, incluso si se está usando un emulador desde la misma máquina.
3. Seguidamente, nos aseguramos que el servicio web no tenga en el URI, el nombre localhost. Esto porque el emulador no encontrará el servicio web, ya que cuando hace referencia a localhost, busca en el Sistema Operativo del emulador. Un ejemplo de cómo debería quedar esta dirección es la siguiente:
this.Url = "http://192.168.1.65/Query/Consulta.asmx";
4. El cuarto paso es levantar y conectar el emulador. Para esto, se procede desde la opción del Visual Studio -> Tools -> Device Emulator Manager a llevar a cabo esta tarea. Una vez en esta pantalla, procedemos a seleccionar la opción conectar, dando clic derecho en el emulador que queremos utilizar. Seleccionamos conectar y esperamos hasta que el ícono de conectado, esté disponible. Seguidamente, seleccionamos en el emulador que esta ejecutándose la opción de Cradle.

5. El siguiente paso es conectar el emulador utilizando el Windows Mobile Device Center. Para tal fin primera mente inicializamos el device center y lo configuramos desde la opción “connection settings” quedando la configuración final de la siguiente forma.

Seguidamente agregamos el loopback adapter como un dispositivo de red en el sistema operativo ( agregar software – dispositivos de red – Microsoft LoopbackAdapter – y procedemos a establecer este dispositivo, como el dispositivo de red del emulador de la siguiente forma. Para llevar a cabo esta tarea, ubicamos la pantalla del emulador ( donde se ve el teléfono) y seleccionamos File-Configure. En esta pantalla seleccionamos este adapter como dispositivo de red, tal y como se ve en la siguiente figura.

Y listo, con esta configuración, ya se debe de tener reconocido el dispositivo en el Windows Mobile Device Center y proceder a ejecutar la aplicación móvil desde Visual Studio.