Software y Aplicaciones Web

Blog de desarrollo de software y aplicaciones web

Comentarios Recientes

Comment RSS

MSDN Home Page (Argentina)


C# Corner


AspAlliance.com

Declaración

Las opiniones en este blog se proporcionan "TAL CUAL", sin garantías,  no confieren derechos y no reflejan, necesariamente, la opinión de quienes me contratan.
Algunas cuestiones que se comentan en el blog no son reales, cualquier similitud con alguna persona viva o muerta no es más que una coincidencia, tampoco significa que necesite terapia, soy asi.

© Copyright 2007-2010

Propaganda

Este sitio implementa publicidad basada en intereses
Dec
8.
2008

  Windows Communication Foundation - 2

WCF - Windows Communication Foundation (ejemplo con DataContract)

Continuando con los ejemplos inciados en WCF - Parte 1, ahora vamos a ver cómo se hace para manejar datos no estándares (clases)

Para ver como se hace una solución y proyectos de este tipo vean (WCF - Parte 1), a continuación está el código de que deben poner en el mismo ejemplo de la parte 1. Se trata de operaciones matemáticas con numeros complejos.

 

 

Componente: Service1.svc.cs

using System.ServiceModel.Activation;
 
namespace WcfService1
{
    // Clase de servicio, implementa el contrato
    /// <summary>
    /// Clase de servicio, es la que implementa el contrato de servicio que se 
    /// indica en la interfaz IService1
    /// </summary>
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1 : IService1
    {
        public ComplexNumber Add(ComplexNumber n1, ComplexNumber n2)
        {
            return new ComplexNumber(n1.Real + n2.Real, n1.Imaginary + n2.Imaginary);
        }
 
        public ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2)
        {
            return new ComplexNumber(n1.Real - n2.Real, n1.Imaginary - n2.Imaginary);
        }
 
        public ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2)
        {
            double real1 = n1.Real * n2.Real;
            double imaginary1 = n1.Real * n2.Imaginary;
            double imaginary2 = n2.Real * n1.Imaginary;
            double real2 = n1.Imaginary * n2.Imaginary * -1;
            return new ComplexNumber(real1 + real2, imaginary1 + imaginary2);
        }
 
        public ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2)
        {
            ComplexNumber conjugate = new ComplexNumber(n2.Real, -1 * n2.Imaginary);
            ComplexNumber numerator = Multiply(n1, conjugate);
            ComplexNumber denominator = Multiply(n2, conjugate);
            return new ComplexNumber(numerator.Real / denominator.Real, numerator.Imaginary);
        }
 
        public ComplexNumber NewComplexNumber(double real, double imaginary)
        {
            return new ComplexNumber(real, imaginary);
        }
    }
}

 

Componente: IService1.cs  

using System.Runtime.Serialization;
using System.ServiceModel;
 
namespace WcfService1
{
    /// <summary>
    /// Interface para el contrato de servicio.
    /// Define las operaciones que se pueden realizar con este servicio
    /// </summary>
    [ServiceContract]
    public interface IService1
    {
        /// <summary>
        /// Suma numeros complejos
        /// </summary>
        /// <param name="n1">Nro Complejo</param>
        /// <param name="n2">Nro Complejo</param>
        /// <returns>Resultado de sumar n1 y n2</returns>
        [OperationContract]
        ComplexNumber Add(ComplexNumber n1, ComplexNumber n2);
 
        /// <summary>
        /// Resta numeros complejos
        /// </summary>
        /// <param name="n1">Nro Complejo</param>
        /// <param name="n2">Nro Complejo</param>
        /// <returns>Resultado de restar n2 a n1</returns>
        [OperationContract]
        ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2);
 
        /// <summary>
        /// Multiplica numeros complejos
        /// </summary>
        /// <param name="n1">Nro Complejo</param>
        /// <param name="n2">Nro Complejo</param>
        /// <returns>Resultado de multiplicar n1 por n2</returns>
        [OperationContract]
        ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2);
 
        /// <summary>
        /// Divide numeros complejos
        /// </summary>
        /// <param name="n1">Nro Complejo</param>
        /// <param name="n2">Nro Complejo</param>
        /// <returns>Resultado de dividir n1 en n2</returns>
        [OperationContract]
        ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2);
 
        /// <summary>
        /// Crear un numero complejo
        /// </summary>
        /// <remarks>
        /// El problema de esta operacion es que instancia el objeto del lado del servidior
        /// y lo transfiere, es LENTO !!!!!!!!!!!!!!1
        /// pero no hay otra alternativa para objetos que requieren lógica de construccion
        /// En este caso es solo un ejemplo, y de hecho esa caracteristica debe evitarse en
        /// las aplicaciones que consumen servicios web, simplemente tienen que les envía el
        /// el servidor y en caso de mandar algo debe ser plano.
        /// </remarks>
        /// <param name="real">Parte real</param>
        /// <param name="imaginary">Parte imaginaria</param>
        /// <returns>Numero complejo</returns>
        [OperationContract]
        ComplexNumber NewComplexNumber(double real, double imaginary);
 
    }
 
    /// <summary>
    /// Clase para definir que es un numero complejo
    /// Define los datos que se transfieren
    /// </summary>
    [DataContract]
    public class ComplexNumber
    {
        [DataMember]
        public double Real;
        [DataMember]
        public double Imaginary;
 
        /// <summary>
        /// Constructor especializado
        /// <remarks>
        ///    Este constructor solo se visulaiza del lado del servidor, en el lado del cliente
        ///    se pude usar el constructor por defecto y acceder a cada propiedad
        /// </remarks>
        /// </summary>
        /// <param name="real">parte real</param>
        /// <param name="imaginary">parte imaginaria (la que se multiplica por i)</param>
        public ComplexNumber(double real, double imaginary)
        {
            this.Real = real;
            this.Imaginary = imaginary;
        }
 
    }
 
}

Acá tenemos dos puntos interesantes:

  • DataContrac. Indica que se trata de un contrato de datos, es la especificación de datos que utilizamos en el servicio.
  • DataMember. Indica que se trata de un dato (campo) que se muestra en el contrato de datos y el cliente lo puede manipular dado que la visibilidad que le damos es public (eso significa que podemos tener campos private ???).
 

En el otro proyecto recuerden referenciar o actualizar al nuevo servicio (obviamente despues de compilarlo) hay que cambiar el componente Program.cs y copiamos el siguiente código:

Componente: Program.cs  

using System;
 
// IMPORTANTE, esto hace falta para manejar las clases definidas en el servicio !!!
using ConsoleApplication1.ServiceReference1;
 
namespace ConsoleApplication1
{
    /// <summary>
    /// Esta clase es la que define por donde comienza la aplicación
    /// </summary>
    class Program
    {
        /// <summary>
        /// Este el metodo inicial de la aplicación
        /// </summary>
        static void Main()
        {
            // Crear el cliente
            ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
 
            // Call the Add service operation.
            ComplexNumber value1 = new ComplexNumber(); value1.Real = 1; value1.Imaginary = 2;
            ComplexNumber value2 = new ComplexNumber(); value2.Real = 3; value2.Imaginary = 4;
            ComplexNumber result = client.Add(value1, value2);
            Console.WriteLine("Add({0} + {1}i, {2} + {3}i) = {4} + {5}i",
                    value1.Real, value1.Imaginary, value2.Real, value2.Imaginary, result.Real, result.Imaginary);
 
            // Call the Subtract service operation.
            value1 = new ComplexNumber(); value1.Real = 1; value1.Imaginary = 2;
            value2 = new ComplexNumber(); value2.Real = 3; value2.Imaginary = 4;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0} + {1}i, {2} + {3}i) = {4} + {5}i",
                    value1.Real, value1.Imaginary, value2.Real, value2.Imaginary, result.Real, result.Imaginary);
 
            // Call the Multiply service operation.
            value1 = new ComplexNumber(); value1.Real = 2; value1.Imaginary = 3;
            value2 = new ComplexNumber(); value2.Real = 4; value2.Imaginary = 7;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0} + {1}i, {2} + {3}i) = {4} + {5}i",
                    value1.Real, value1.Imaginary, value2.Real, value2.Imaginary, result.Real, result.Imaginary);
 
            // Call the Divide service operation.
            value1 = new ComplexNumber(); value1.Real = 3; value1.Imaginary = 7;
            value2 = new ComplexNumber(); value2.Real = 5; value2.Imaginary = -2;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0} + {1}i, {2} + {3}i) = {4} + {5}i",
                    value1.Real, value1.Imaginary, value2.Real, value2.Imaginary, result.Real, result.Imaginary);
 
            // Cerrar el cliente y liberar los recursos
            client.Close();
 
            Console.WriteLine();
            Console.WriteLine("Pulse <ENTER> para finalizar.");
            Console.ReadLine();
        }
    }
}
 

 

Listo, ahora se puede probar.

Espero que lo puedan  hacer, sino se bajan el código completo WcfDemo2.zip (42,08 kb) y lo prueban. 

 




Marcas: ,
Categorías: ASP.NET | WCF



Comments (5) -

Pablo Argentina

Friday, December 26, 2008 10:58 PM

Pablo

Julio, podrías poner un ejemplo de WorkFlow?
Gracias

jtentor Argentina

Tuesday, February 03, 2009 2:56 AM

jtentor

Estuve descansando, en unos días subo algo.

green Colombia

Wednesday, February 11, 2009 11:09 PM

green

Unas dudas, los contratos son las entidades de mi negocio?, si es así, es mejor tener un proyecto de dominio que maneje tales entidades, entonces los datos de una entidad que se pasaran del proyecto de servicios wcf a mi proyecto donde se ubica la lógica de negocios podria ser un array de datos? y desde allí sí referenciar al proyecto que alberga las entidades.

gracias.

Julio Tentor Argentina

Friday, February 13, 2009 2:04 PM

Julio Tentor

En una pequeña aplicación puede ser que "Entidad de Negocio" = "Contrato de Servicio"; pero no recomendaría plantear las cosas de ese modo.

El término contrato se refiere justamente a un "acuerdo" entre aquellos que van a consumir un servicio y quién lo va a proveer. De este modo una aplicación cuenta con toda una capa de entidades de negocio que dan soporte a esa aplicación y probablemente a otras, mientras que los contratos son métodos que se publican para lograr solamente un servicio en particular.

Un contrato puede ser solamente un metodo con algunos argumentos o parámetros y en ninguna parte se especifica las clases o estructuras de datos que estan involucradas, obviamente es mucho mas facil publicar una pequeña estructura que a veces puede coincidir con las propiedades de alguna entidad de negocio en lugar de utilizar un arreglo que necesita explicaciones de qué es lo que hay en cada posición (claró que si solamente se tratase de nombres de personas entonces no hay ningún problema, pero si también hay que pasar otra información como domicilios, fechas u otros datos es mejor una estructura o clase).

Si analizas el post (www.jtentor.com.ar/.../...-Capas-y-N-Niveles.aspx) donde comento cuestiones de arquitectura puedes ver con mayor claridad la manera en que recomiendo se organicen los assemblies cuando se trata de una aplicación de mediana envargadura. Ahí se puede ver como la capa que se encarga de los servicios utiliza entidades DTO (Data Transfer Object), solo sirven para transferir información a diferencia de las entidades de negocio que además de mantener la información presentan el comportamiento.

Finalmente te comento que estoy de acuerdo con tu opinión salvo el tema del array de datos, particularmente prefiero definir estructuras o clases.

Kampanye Damai Pemilu Indonesia 2009

Wednesday, April 29, 2009 9:03 AM

Kampanye Damai Pemilu Indonesia 2009

thanks for this usefull informations.. now i find what i want to know.. thanks a lot..

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading