Introducción a Windows Communication Foundation PARTE 4
Aproximación al desarrollo de servicios con WCF
Si bien esta nota no es un tutorial, en esta parte mostraremos las diferentes partes que se pueden dar durante la programación de un servicio.
Hay tres formas de encarar un proyecto de WCF
- Por Código: implica crear primero el código de implementación del servicio, luego la definición del contrato y finalmente la descripción del servicio, ésta última se brinda mediante un MEX Endpoint (MetadataExchange) o archivos WSDL y XSD; no todos los tipos de clases pueden ser convertidos a un esquema XSD siendo esta su desventaja.
- Por Contrato: implica crear primero la definición del contrato, luego la descripción del servicio. La descripción del servicio permite implementar el cliente generando código a partir de los metadatos. Finalmente se crea el Código de implementación. Esta es una aproximación ideal.
- Sin contrato: no se considera el contrato y es ideal para trabajar a nivel de mensajes. Se deben crear los mensajes a enviar e interpretar los recibidos, se puede utilizar esta técnica si el servicio debe aceptar cualquier tipo de mensaje como por ejemplo un servicio de ruteo.
Para las alternativas anteriores nos podemos apoyar en las facilidades de generación de código ya sea para un cliente, metadatos, etc. Esto se puede realizar a través de la herramienta SvcUtil que está disponible con el SDK, se encuentra por defecto en el path “C:\Archivos de programa\Microsoft SDKs\Windows\v6.0\Bin\” y o Visual Studio y nos permite entre otras cosas:
- Generación del código del cliente a partir de un servicio en ejecución o documentos de metadatos online
- svcutil http://service/metadataEndpoint
- Generar tipos de Data Contracts a partir de un servicio en ejecución o documentos de metadatos online
- svcutil /dconly http://service/metadataEndpoint
- Generar código en diferentes lenguajes
- svcutil *.wsdl *.xsd /language:C#
- svcutil /dconly *.xsd /language:VB
- Descargar documentos de metadatos desde un servicio en ejecución
- svcutil /t:metadata http://service/metadataEndpoint
- Generar metadatos
- svcutil myAssembly.dll
- svcutil myServiceHost.exe /serviceName:myServiceName
- Mediante Visual Studio
- Agregando una referencia a un servicio de WCF genera el Proxy para ser utilizado por el cliente.
El desarrollo de un servicio puede ser realizado definiendo por código todas sus particularidades mediante atributos, por un archivo de configuración o una combinación de ambos. En los siguientes ejemplos mostramos las alternativas:
Ejemplos por Código
[ServiceContract]
public interface IReservacion
{
[OperationContract]
iniciar(string nombre);
}
...
Uri direccion = new Uri("http://localhost:8080/CalculadoraService/");
serviceHost = new ServiceHost();
serviceHost.AddEndpoint( typeof(IMyContract), new WSProfileBinding(),direccion);
...
Ejemplos por Configuración
Especifica varias de las características de un servicio a través de un archivo de configuración (address, binding, seguridad, comportambiento, etc). Disponemos para esto de la herramienta Service Configuration Editor referido anteriormente para asistirnos en la creación del archivo.
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.serviceModel>
<services>
<service serviceType="MiServicio">
<endpoint
address=http://localhost:8000/ MiServicio /
bindingSectionName="basicProfileBinding"
contractType="IMiContrato" />
service>
services>
system.serviceModel>
configuration>
Pasos para crear un servicio con WCF
- Crear una definición una interfaz .NET (Contrato del servicio)
[ServiceContract()]
public interface ICalculadora
{
[OperationContract()]
double Suma(double o1, double o2);
[OperationContract]
double Resta(double o1, double o2);
[OperationContract]
double Multiplicacion(double o1, double o2);
[OperationContract]
double Division(double o1, double o2);
}
- Implementar el Contrato y Comportamiento del servicio en una clase .NET (Tipo de Servicio)
[ServiceBehavior()]
public class Calculadora : ICalculadora
{
[OperationBehavior()]
public double Suma(double o1, double o2)
{
Console.WriteLine("Ejecutando Suma");
return o1 + o2;
}
[OperationBehavior]
public double Resta(double o1, double o2)
{
Console.WriteLine("Ejecutando Resta");
return o1 - o2;
}
[OperationBehavior]
public double Multiplicacion(double o1, double o2)
{
Console.WriteLine("Ejecutando Multiplicacion");
return o1 * o2;
}
[OperationBehavior]
public double Division(double o1, double o2)
{
Console.WriteLine("Ejecutando Division");
return o1 / o2;
}
}
- Programar el inicio del servicio
public class CalculadoraManager
{
private static ServiceHost _serviceHost = null;
public static void StartService()
{
Uri direccion = new Uri("http://localhost:8080/CalculadoraService/");
_serviceHost = new ServiceHost(
typeof(CalculadoraService.Calculadora), direccion);
}
public static void StopService()
{
if (_serviceHost.State != CommunicationState.Closed)
{
_serviceHost.Close();
_serviceHost = null;
}
}
}
- Configurar característicasdel servicio en App.Config
xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" />
basicHttpBinding>
<mexHttpBinding>
<binding name="NewBinding1" />
mexHttpBinding>
bindings>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior">
<serviceMetadata httpGetEnabled="true" />
behavior>
serviceBehaviors>
behaviors>
<services>
<service name="CalculadoraService.Calculadora">
<endpoint address="http://localhost:8888/"
binding="basicHttpBinding"
bindingConfiguration="NewBinding0"
contract="CalculadoraService.ICalculadora"/>
<endpoint binding="mexHttpBinding"
bindingConfiguration="NewBinding1"
contract="IMetadataExchange" />
service>
services>
system.serviceModel>
configuration>
- Alojar el servicio utilizando la infraestructura WCF.
- Mediante un servicio de Windows
- En IIS
- Aplicación
- Otras
Definición de Endpoint utilizando completamente la API de WCF.
Definición de contrato por código mediante atributos: