miércoles, 23 de julio de 2008

[WCF] El primer servicio

Bueno... como lo prometido es deuda vamos a ver como crear nuestro primer servicio usando WCF!!!! Jejeee... os embarga la emoción, eh??? ;-)

Cuando creamos un servicio en WCF, lo primero es pensar cual será su contrato, es decir, cuales serán las operaciones que este servicio expondrá a sus clientes. Por ejemplo, vamos a hacer un servicio calculadora, que servirá para realizar cálculos. Para ello, voy a definir que mi servicio tendrá los métodos Sumar, Restar, Multiplicar y Dividir. Este sería a grandes rasgos el contrato del servicio.

Como creamos un WCF en Visual Studio 2008? Pues nos vamos a "New Project" y dentro de la categoría WCF escogemos algo así como "WCF Service Library". Lo que vamos a crear será un assembly (concretamente una DLL) que contendrá uno o más servicios. Le pongo al proyecto el nombre de ServiciosCalculo.


 Lo primero que vemos es que VS ha creado el proyecto y le ha añadido tres archivos:
  1. App.config
  2. IService1.cs
  3. Service1.cs
El fichero App.config, es el fichero clásico de configuración de aplicación de .NET. Porque nos añade uno VS??? Pues bien, porque WCF se puede configurar usando el fichero App.config.


El fichero IService1.cs contiene una interfaz. Y que es esta interfaz? Pues el contrato de mi servicio, ni más ni menos. Además es lógico no? Cual es la manera de declarar los métodos que implementa una clase en .NET? Las interfaces. Pues WCF usa este mecanismo, y todo servicio en WCF debe implementar una interfaz.

Vamos pues a declarar el código de nuestro servicio. Modificamos el archivo IService1.cs para que quede así:
namespace ServiciosCalculo
{
    [ServiceContract]
    public interface ICalculadora
    {
        [OperationContract]
        double sumar(double a1, double a2);
        [OperationContract]
        double restar(double a1, double a2);
        [OperationContract]
        double multiplicar(double a1, double a2);
        [OperationContract]
        double dividir(double a1, double a2);
    }
}



Si os fijais la interfaz está decorada con el atributo [ServiceContract]. Esto le indica a WCF que esta es una interfaz que algún servicio implementará. Cada operación de la interfaz debe ir decorada con [OperationContract]. Si no ponemos [OperationContract] en el método, este pertenecerá a la interfaz, pero NO al contrato del servicio (es decir será un método no accesible desde WCF).

Ok, ya tenemos un contrato... y el servicio? Pues muy fácil, editamos el fichero Service1.cs para que quede algo así:

    public class CalculadoraService : ICalculadora
    {
        public double sumar(double a1, double a2)
        {
            return a1 + a2;
        }
        public double restar(double a1, double a2)
        {
            return a1 - a2;
        }
        public double multiplicar(double a1, double a2)
        {
            return a1 * a2;
        }
        public double dividir(double a1, double a2)
        {
            return a1 / a2;
        }
    }


Fijaos en una cosa: la clase que implementa el servicio NO tiene ninguna decoración especial. No usamos ningún servicio ni nada para indicar que esta clase es un servicio. El hecho que implemente una interfaz decorada con [ServiceContract] le basta a WCF para saber que esta clase es un servicio.

Venga... como se que la emoción os emarga!! Dadle a F5! Os preguntais que pasará??? Generalmente las DLLs no se pueden ejecutar (necesitamos un .exe), pero en el caso de las WCF Service Library, Visual Studio pone en marcha un host de servicios propio que nos permite probar nuestros servicios sin necesidad de hacernos una aplicación que los hospede ni un cliente!

Pues bueno... si le dais a ejecutar, aparece... un mensaje de error (algo así como "The client was unable to retrieve service metadata. Make sure the service is running and exposing metadata"). Oooops... nuestro gozo en un pozo.
Vamos a ver que ha pasado...

... la clave, como no podia ser de otro modo, está en el único fichero que no hemos tocado... el app.config.  En este fichero estan las configuraciones de todos los servicios de nuestra libreria. Recordad que un servicio debe tener un Endpoint: es decir, una dirección, un binding y un contrato. Lo del contrato lo tenemos claro, pero... vosotros habeis especificado una dirección (URI) para el servicio? Y un binding? No, verdad? Es que todo esto se especifica en el archivo de configuración.
VS.NET cuando hemos creado el proyecto ha creado uno para nosotros. No entraremos en detalles ahora (tendremos tiempo), pero echando una ojeada, descubrireis el problema: el fichero app.config generado por el Visual Studio utiliza los nombres IService1 y Service1 para declarar el servicio. Y estas clases no existen (les hemos cambiado el nombre), así que reflejamos los cambios en el app.config.

Concretamente los cambios a realizar son:
  • En el tag <service> el atributo name debe tener el nombre de la clase (en nuestro caso ServiciosCalculo.CalculadoraService).
  • En el tag <endpoint> el atributo contract debe tener el nombre del contrato, es decir de la interfaz. En nuestro caso ServiciosCalculo.ICalculadora.
 En principio no es necesario cambiar nada más. Compilad y ejecutad el proyecto de nuevo y os aparecerá el WCF Test Client:




Podeis ver que VS ha arrancado el WCF Service Host (para hospedar nuestro servicio) y un cliente de prueba (el WCF Test Client) para que podais probar el servicio. Haciendo doble click en uno de los métodos de nuestro servicio, el WCF Test Client lo invocará y nos mostrará el resultado. Aquí teneis un ejemplo de una llamada a dividir:


Que os parece? Fácil, no? Pues en el proximo post veremos un poco más en detalle como funciona el fichero app.config.
Hasta entonces.... nos leemos ;-)

jueves, 10 de julio de 2008

[WCF] El ABC de WCF

Bueno... segundo post de la serie de WCF, donde sigo con la introducción.
En el primer post vimos que WCF era la nueva api de comunicaciones del Framework 3, orientada a servicios y con vocación de convertirse en la API de comunicaciones definitiva.

Bueno, desarrollar en WCF, consiste básicamente en hacer servidores que exponen servicios y clientes que los consumen. La relación entre un cliente y un servicio es un fiel reflejo de la vida real... veamos, podemos ver un cliente como alguien muy enamorado de la chica de sus sueños. Al final nuestro enamorado se decide lanzar a la dificil tarea de conquistar a su dama.... aaahhh.... el romanticismo....


Ante tan árdua tarea, seguro que te van a asaltar las siguientes dudas:
  1. Donde vive?
  2. Cómo hablarle?? Prefiere a los románticos, a los que van de duros o tiene debilidad por los tímidos y calladitos?
  3. Qué decirle?? Probablemente la clave entre el éxito y el fracaso está en este punto.... Quien no ha estropeado un largo trabajo de conquista con una frase que, digamos... no tocaba.
Pues como si un Don Juan cualquiera se tratase, esas tres dudas, el Donde, el Cómo y el Qué, son los tres datos que todo cliente necesita para poder consumir un servicio:
  1. Donde está? Es decir, en que URI se localiza?
  2. Cómo hablarle? Es decir, que protocolo usar? Qué codificación de datos?
  3. Qué decirle? Es decir, qué métodos se pueden invocar del servicio? Cual es su interfaz?
A las respuestas a esas tres cuestiones (fundamentales), se las conoce como el ABC de WCF, no sólo porque sean realmente lo básico (que lo son) de WCF si no porque:
  1. Donde está un servició es su dirección. En inglés Address.
  2. Como hablarle es el enlace a usar. En inglés Binding.
  3. Qué  le podemos decir es el contrato  del servicio. En inglés Contract (esa era fácil).
Address, BInding y Contract, ABC, esos tres puntos son los que tenemos que tener siempre en mente. De hecho la suma de los tres es lo que se llama un Endpoint.
En WCF los servicios pueden tener uno o varios endpoints, y los clientes cuando quieren consumir un servicio, pueden escojer a través de que endpoint quieren hacerlo.

Parad atención al tema de que un servicio puede tener más de un endpoint... por ejemplo, podría tener dos endpoints con el mismo contrato pero con direcciones y bindings distintos... Un binding podria ser acceder al servicio a través de http usando soap y el otro binding podria ser usando msmq con codificación binaria... El servicio es el mismo, solo cambia el protocolo y la codificación de datos a usar (y la URI de nuestro servicio). Cuando el cliente quiere consumir este servicio decide si quiere (generalmente si puede xD) hacerlo usando http y soap, o bien usa msmq y datos binarios. Pero de nuevo el cliente es el mismo.


Y cuando digo mismo, quiero decir eso: mismo. El mismo código. El mismo programa. La misma clase.


Esa es la clave de WCF. Por eso se dice que unifica a todas las APIs anteriores.


En la próxima entrega... empezaremos ya a ver código de como hacer un servicio en WCF!


miércoles, 2 de julio de 2008

[WCF] Introducción

Bueno... voy a empezar con este una serie de posts dedicados a WCF, uno de los grandes pilares del framework 3 y que a mi, personalmente, me encanta...
Que es WCF? Bueno... pues resumiendo podriamos decir que se trata de una nueva API para la comunicación de aplicaciones o procesos. Sï, sí... una nueva API más. Hombre, la primera pregunta que uno se hace es si es necesaria otra API más, ya que en la historia microsoft relativamente reciente (vamos .NET) tenemos ya un buen número de APIs que se encargan de comunicar procesos de alguna manera u otra:
  1. System.Messaging: Para el uso de colas de mensajes, donde ni emisor ni receptor deben estar on-line.
  2. Servicios web asmx: Para la realización de servicios web en ASP.NET, que permiten interoperar aplicaciones realizadas en distintas tecnologias.
  3. WSE: Añade mejoras a los servicios web de ASP.NET para permitir el soporte de estándares más avanzados.
  4. .NET Remoting: Para el uso de aplicaciones .net basadas en objetos distribuidos.
  5. Enterprise Services: Para el uso de servicios COM+
En resumen... 5 APIs distintas para realizar lo mismo: comunicar procesos. Claro está que cada una tiene sus características y debe evaluarse cual debe usarse en cada caso... y ahí radica el primer problema: cuando arquitecturamos una aplicación tenemos que decidir cual de esas APIs vamos a usar para comunicar la aplicación con el exterior. Ojo, que son APIs completamente distintas, así que si nos equivocamos, cambiar de una a otra no es fácil.
Y ahora, aparece una nueva API... qué podemos decir de ella?
Pues básicamente que WCF es a las APIs de comunicaciones lo que el Anillo Único es en los Anillos de Poder: es una API para dominarlas a todas.

Para entendernos: WCF unifica todas las APIs de comunicaciones previamente existentes en una de sola. Da igual si vamos a usar web services, COM+, objetos distribuidos en .NET o colas de mensajes asíncronas: usaremos WCF para desarrollar la aplicación. Eliminamos pues la decisión de que API usar. A grosso modo podríamos decir que no hay necesidad en el framework 3, de usar ninguna de las otras APIs existentes (que evidentemente se mantienen): todo podemos hacerlo usando una sola API, usando WCF.

A los que tengais experiencia en la creación de aplicaciones distribuidas en .NET, esto igual os suena un poco a quimera: conceptualmente Servicios Web asmx y System.Messaging se parecen como un huevo a una castaña... ¿cómo se han podido unificar? Pues tranquilos: veremos que se ha podido y como se ha hecho ;-)

De momento vamos a quedarnos con dos conceptos clave:
  1. WCF unifica todo el resto de APIs de comunicaciones que existían en el universo .NET
  2. WCF es una API orientada a servicios: Los servidores exponen servicios que los clientes consumen.
En el próximo post vermos lo que los anglosajones llaman el ABC de WCF...

Saludos!

martes, 1 de julio de 2008

C# es fácil (v): Inicialización de objetos

En C# 3.0 se ha añadido la capacidad de crear e inicializar un objeto en una única sentencia. Antes, esto no era posible (excepto cuando se usaba una clase como un atributo y era más un apaño que otra cosa). Tampoco es que sea una novedad impactante, simplemente nos permite hacer el código un poco más cómodo, pero vamos... tampoco vamos a lanzar cohetes por esto :)
Ahora, cuando creamos un objeto, junto con el new, podemos invocar tantas propiedades (públicas) como deseemos, para dejar el objeto en el estado que nosotros queramos. Por ejemplo, imaginemos una clase Perro, tal y como sigue:
enum RazaPerro
{
    Terrier,
    BullDog,
    PastorAleman,
    Cocker,
    Basset,
    Monstruosa
}
class Perro
{
    public Perro()
    {
        _raza = RazaPerro.Terrier;
    }
    private int _edad;
    public int Edad
    {
        get { return _edad; }
        set { _edad = value; }
    }
    private Color color;
    public Color Color
    {
        get { return color; }
        set { color = value; }
    }
    private RazaPerro _raza;
    internal RazaPerro Raza
    {
        get { return _raza; }
        set { _raza = value; }
    }
}
Hasta ahora, si queriamos crear un Perro Mutante, digno de las mejores pesadillas, teníamos que hacer:
Perro monstruoso = new Perro();
monstruoso.Color = Color.Green;
monstruoso.Edad = 10;
monstruoso.Raza = RazaPerro.Monstruosa;

Pues ahora, gracias a la inicialización de objetos podemos hacerlo en una sola placentera linea:
Perro mutante = new Perro() { Color = Color.Green, Edad = 2, Raza = RazaPerro.Monstruosa };

Bueno... no hagais esa cara... ya os dije que tampoco había para tanto.... :)
Relacionado con la inicialización, decir que se ha añadido también la capacidad de "inicializar" colecciones... entendiendo por colección un objeto de cualquier clase que implemente IEnumerable. O sea que ahora puedo hacer esto:
List<Perro> SabuesosDelOscuro = new List<Perro>() { monstruoso, mutante };

De nuevo, tampoco revoluciona el panorama de los leguajes orientados a objetos, pero nos permite escribir código más compacto y más claro.
Con esto, a lo largo de la serie "C# es fácil", hemos repasado las principales novedades del lenguaje C# 3.0... en la próxima entrega veremos como se combinan todas ellas para dar lugar a una de las novedades más importantes: LINQ.
Nos vemos! ;-)