WCF bajo contrato (1/4)


Como continuación al artículo Servicios Web con WCF: Una sencilla introducción a Servicios Web con WCF, la presente serie abordará de manera sencilla los principales tipos de contratos que se emplean para definir los Servicios de WCF. La finalidad es dar una introducción práctica a los mismos, sin pretender ser exhaustivo. Así que partiendo del servicio Hello del artículo anterior, comencemos por el Contrato de Servicio.

Contrato de Servicio

Un contrato de servicio permite la comunicación con el mismo, al proporcionar la siguiente información:

  • Listado de las operaciones que ofrece y la ubicación de las mismas
  • Firma de las operaciones, en términos de intercambio de mensajes
  • Tipos de datos empleados en los mensajes.
  • Protocolos concretos y formatos de serialización.

Para esto se utilizan los documentos WSDL y XSD, que son lenguajes estándar para describir servicios web. No obstante WSDL y XSD son difíciles de utilizar, por ello en WCF se utilizan atributos, interfaces y clases para definir la estructura de un servicio.

En el artículo Servicios Web con WCF se define el contrato del servicio utilizando la clase de implementación del mismo. Sin embargo es recomendable utilizar una interfaz para ello, ya que, al igual que un contrato de servicio, las interfaces solo definen la agrupación de métodos (operaciones) con ciertas firmas sin especificar ningún detalle sobre su implementación. Además, todas las ventajas de las interfaces administradas se aplican a las interfaces de contrato de servicio:

  • Las interfaces pueden extender cualquier número de interfaces
  • Una única clase puede implementar cualquier número de interfaces
  • Puede modificar la implementación de una interfaz, mientras la interfaz siga siendo la misma

Por lo que adicionalmente se puede controlar la versión del servicio implementando la interfaz antigua y la nueva. Los clientes antiguos se conectan a la versión original, mientras los clientes más nuevos pueden conectarse a la versión más nueva.

Así que, tras realizar refactoring al Servicio WCF Hello, el contrato y su implementación ahora quedan de la siguiente forma:

Listado de Hello.cs

using System;
using System.Text;
using System.ServiceModel;

namespace hello
{  

  [ServiceContract(Namespace="http://hello/, Name="Hello")]
  interface IHello
  {
    [OperationContract()]
    string SayHello(string name);
  }
    
  [ServiceBehavior(Namespace="http://hello/", Name="HelloService")]    
  public class Hello : IHello
  {
    private StringBuilder message = new StringBuilder("!Hola ");

    public string SayHello(string name)
    {
      if (name == null || name.Length == 0)
        throw new FaultException("Parámetro 'name' nulo o vacío.");
      string msg = message.Append(name + "!").ToString();
      System.Console.WriteLine(msg);
      return msg;
    }
  }
}

Observe que ahora los atributos ServiceContract y OperationContract se aplican a la interfaz, y que a la clase de implementación sólo se la aplica el atributo ServiceBehavior. Recuerde que los dos primeros atributos definen el contrato del servicio y sus operaciones, mientras que el tercero define comportamientos concretos de la implementación. En el ejemplo los utilizamos para marcar las responsabilidades de cada una, así como el namespace a utilizar en la exportación hacia el WSDL.

Tras compilar el servicio:

>csc /t:library Hello.cs /r:System.ServiceModel.dll

Continuamos con el host. El código de HelloHost.cs permanece sin cambios, pero tenemos que hacer un ligero cambio al archivo de configuración HelloHost.exe.config, de modo ahora el atributo contract del endpoint señale a la interfaz:

Listado de HelloHost.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="hello.Hello" behaviorConfiguration="enableMetadata">
        <endpoint contract="hello.IHello" binding="basicHttpBinding" address="" 
            bindingNamespace="http://hello/" name="HelloPort" />
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="enableMetadata" >
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Nota: En lo sucesivo el host y su archivo de configuración no serán alterados.

Del lado servidor solo resta ejecutar el host:

>HelloHost.exe

El Servicio Web Hello se esta ejecutando...
WSDL: http://localhost:8080/Hello?wsdl
Presione una tecla para cerrarlo.

Ahora vamos con el cliente. Primero debemos regenerar los artefactos cliente con svcutil.exe:

>svcutil http://localhost:8080/hello?wsdl /out:Hello.cs /config:Client.exe.config /n:http://hello/,hello

Después modificamos una línea del código de la aplicación cliente (en negrita):

Listado de Client.cs

using System;

public class Client
{
  static void Main(string[] args)
  {
    String arg = null;
    String result = null;
    if (args.Length > 0) {
      arg = args[0];
    }
    else {
      arg = "Anónimo";
    }
    try {      
      hello.Hello service = new hello.HelloClient();
      result = service.SayHello(arg);
    }
    catch (System.ServiceModel.FaultException fault) 
    { 
      result = "Fault: " + fault.Message; 
    }
    catch (Exception ex) {
      result = ex.ToString();
    }
    finally{
      System.Console.WriteLine(result);
    }
  }
}

Observe que la interfaz que define el contrato del servicio en el cliente se llama Hello en lugar de IHello, eso se debe a que así se especificó en el parámetro por nombre “Name” del atributo ServiceContract de la interfaz IHello en el servicio.

Compilamos tanto el proxy como la aplicación:

>csc /t:library Hello.cs /r:System.ServiceModel.dll

>csc /t:exe Client.cs /r:System.ServiceModel.dll,Hello.dll

Y la ejecución será la misma que la última vez:

>Client Willy

Hola Willy.

Acerca de Willy Mejia

Developer, Techie, Human... http://about.me/willyxoft
Esta entrada fue publicada en .NET, NetFx3, WCF. Guarda el enlace permanente.

Una respuesta a WCF bajo contrato (1/4)

  1. Pingback: WCF bajo Contrato (3/4) « WillyXoft

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s