martes, 9 de diciembre de 2014

Introducción a WCF - Fase I

En el siguiente articulo estaré hablando acerca de WCF - Windows Communication Foundation, considerando que este apartado es la parte introductoria al tema de servicios:

Requisitos:
Visual Studio 2012.
Lenguaje de programación C#.

¿Qué es WCF?
Revisando en la internet se encontrará mucha información al respeto, en resumen es uno o más de las apliaciones que se implementa a una solución o proyecto, con la única diferencia que son aplicaciones orientadas a servicios - SOA, para aclarar, esto no quiere decir que el concepto que planteo es solamente crear una aplicación, iré aclarando ciertos puntos que debemos considerar al momento de construir nuestra aplicación. Para mayor detalles pueden revisar el enlace más sobre WCF con respecto a SOA estaré publicando más adelante en otro articulo.

Iniciamos con la creación de nuestra solución DemoWCF:



Crear la solución haciendo referencia al .NET Framework 4.5


Solución creado DemoWCF

Creamos nuestro proyecto PyDemoWCF:


IService1.cs: Clase que invoca todos los métodos (operaciones) creados que retornaran algún valor sin importar el tipo de dato que contiene la clase Service1.cs.
// NOTA: puede usar el comando "Rename" del menú "Refactorizar" para cambiar el nombre de interfaz "IService1" en el código y en el archivo de configuración a la vez.
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value); 
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite); 
// TODO: agregue aquí sus operaciones de servicio
}
El atributo [ServiceContract] se encarga de definir lo que puede realizar un servicio. Además se encarga de describir las operaciones que ofrece un servicio. Es decir, permite la interoperabilidad (operaciones que se puede realizar) de un servicio, intercambiando información entre 2 o más SISTEMAS de una entidad local o varias entidades sin considerar el lugar en la que se encuentre. La importancia de ServiceContract se resume en un ACUERDO entre las partes involucradas que nos permiten definir la manera en que se trabaja entre las partes involucradas. Considerano los tipos de funciones que se van a ofrecer, qué tipos de datos serán enviados o recibidos y el cómo serán enviados.

El atributo [OperationContract] sirve para poder identificar las operaciones (métodos) que se esta realizando, así que, toda operación debe estar en el [ServiceContract] ya que nos permite indicar el acuerdo entre sí. 

// Utilice un contrato de datos, como se ilustra en el ejemplo siguiente, para agregar tipos compuestos a las operaciones de servicio.
// Puede agregar archivos XSD al proyecto. Después de compilar el proyecto, puede usar directamente los tipos de datos definidos aquí, con el espacio de nombres "PyDemoWCF.ContractType".
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello "; 
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
} 
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
Además por defecto trae implementado el [DataContract] que se encarga de describir la estructura de datos manejados por la operaciones de los servicios con sus respectivos miembros de datos [DataMember]. Considerando que omitir un miembro de datos serializados, establezca la propiedad EmitDefaultValue del atributo DataMemberAttribute en false (el valor predeterminado es true), en otro articulo se profundizará el tema de los [DataMember].

Service1.cs Clase que concreta la ejecución de todos los métodos (operaciones) creados. Es decir en esta clase es la que se implementa todas la operaciones sea cual sea, traerdatosempleado, procesarsuelto, procesarnota, etc.

// NOTA: puede usar el comando "Rename" del menú "Refactorizar" para cambiar el nombre de clase "Service1" en el código y en el archivo de configuración a la vez.
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
} 
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
App.config Archivo que contiene la configuración de nuestro servicio. El punto a resaltar por ahora sera el endpoint. Una aplicación basado en servicio siempre tiene que tener al menos un endpoint, que se encarga de seleccionar la dirección o ruta, quiere decir es fundamental en determinar una ruta para el compartimiento de información entre las parte involucradas en un servicio. Es decir el cliente involucrado debe saber la ruta para poder acceder a dicho servicio.

En nuestro caso esta por defecto la ruta localhost, pero no es solamente este punto de los endpoint's a considerar, hay muchos puntos que más adelante hablaremos sobre las https, las adrresses el tcp y behavior, entre otros.

Testeando nuestro Servicio:
// Aquí implementamos un contrato de datos
[DataContract]
public class OperacionPromedio
{
string alumno;
string especialidad;
string curso;
decimal promedio; 
[DataMember]
public string Alumno{
get { return alumno; }
set { alumno = value; } 
} 
[DataMember]
public string Especialidad
{
get { return especialidad; }
set { especialidad = value; } 
} 
[DataMember]
public string Curso { 
get { return curso; }
set { curso = value; }
} 
[DataMember]
public decimal Promedio
{
get { return promedio; }
set { promedio = value; }
}
}

// Aca invocamos a nuestro método GetNombresApellidos...
[OperationContract]
string GetNombresApellidos(string nombres, string apellidos); 
[OperationContract]
OperacionPromedio GetOperacionPromedio(int pNota1, int pNota2, int pNota3);
//Aca implementaremos un metodo que retorna un valor en cadena
public string GetNombresApellidos(string nombres, string apellidos) {
string dato;
dato = nombres +" "+ apellidos;
return dato;
} 

//Aca implementaremos un metodo que retorna valores utilizando un contrato de datos
public OperacionPromedio GetOperacionPromedio(int pNota1, int pNota2, int pNota3)
{
OperacionPromedio OpePromedio = new OperacionPromedio(); 
OpePromedio.Alumno = "Hadson Paredes Córdova";
OpePromedio.Especialidad = "Computación e Informatica";
OpePromedio.Curso = "Análisis y diseño de procesos";
OpePromedio.Promedio = Decimal.Round((pNota1 + pNota2 + pNota3) / 3, 2); 
return OpePromedio;
}
Crear el proyecto PyDemoWCF de tipo Biblioteca de servicios WCF haciendo referencia al .NET Framework 4.5


En nuestro proyecto creado explicaremos las consideraciones y conceptos de un servicio


Comencemos:

Al crear nuestro proyecto de tipo Biblioteca de servicios WCF por defecto crea los siguientes archivos con los siguientes contenidos.



Todas las operaciones que fueron invocados en la clase IService1.cs es decir string GetData(int value) y CompositeType GetDataUsingDataContract(CompositeType composite) ahora se podrá visualizar la estructura de dichos eventos:


Ambos métodos (Operaciones) son dependientes de la clase IService1 y son de tipo publico.

Para poder realizar el Test de nuestra aplicación implementaré 2 nuevos métodos independientemente de las que comentamos (las que trae por defecto al crear el proyecto Biblioteca de servicios WCF) líneas arriba.

En la clase IService1.cs implementamos un contrato de datos:

Además en el [ServiceContract] hacemos referencia a los métodos GetNombresApellidos y GetOperacionPromedio:

Ahora bien en la clase Service1.cs implementamos  nuestro métodos:

Ahora iniciamos nuestro test, como se vera en la siguiente imagen de la ficha con formato:


Para nuestro test solo se va a realizar con e método GetOperacionPromedio. El cliente de prueba nos ofrece la sección de métodos, solicitud y respuesta.

De la misma manera nos ofrece en la ficha XML con la única diferencia que son datos en XML:



Ahora ingresamos los datos respectivos en la sección de Solicitud:




Y como se visualiza en la sección de respuesta son los valores que se esta retornando según la operación o método en ejecución, que en lo interno se llega a ejecutar. Es decir si el cliente nos envía una solicitud o petición de algo, el servicio siempre tiene que devolver un valor o respuesta verídica o una excepción o error tiene mucho que ver la implementación que se desarrollo. Quiere decir para toda solicitud o petición  habrá algo que devolver o responder.

Veámoslo a motodo XLM:

De esta manera es la que el cliente podrá leer la respuesta de su solicitud.

Bueno, espero que les aya gustado en el siguiente articulo se implementara el proyecto. El como se consume la información a lado del cliente de nuestro servicio creado. Nos vemos...!!!