Archive for the Patrones de Diseño Category

WCF y OperationBehaviors

Posted in ASP.NET, Microsoft, Patrones de Diseño, Tutorial on septiembre 30, 2009 by César Intriago

 

Windows Communication Foundation nos permite desarrollar servicios en .Net  de una manera rápida y sencilla, permitiendo soportar varios endpoints y esquemas de configuración. También ofrece un gran nivel de personalización, uno de ellos es poder escribir OperationBehaviors personalizados para nuestro servicio.

Un OperationBehavior nos permite cambiar y controlar el modo en que WCF ejecuta un método, por ejemplo podemos ejecutar código automáticamente antes de que se llame a una operación o después. Este es el caso que veremos en el siguiente ejemplo:

Creación del Servicio

Ok manos a la obra, lo primero es crear un nuevo proyecto WCF, el cual llamaremos “CalculatorService”

image

Luego agregamos dos operaciones a nuestro servicio, tanto en la interfaz como en la implementación: Add y Substract, como se ve en la siguiente figura:

image

Estas dos funciones lo que hacen es agregar y restar un valor de la variable de instancia _currentValue.

Ejecutamos el proyecto, y Visual Studio abrirá un cliente básico para poder probar nuestro servicio:

image

Behaviors

Ahora haremos algo interesante: Cada vez que se llame al método Add o Substract invocaremos de forma automática a un tercer método llamado “Audit”, esto lo hacemos usando OperationBehviors que nos permitirá tener acceso a personalizar la invocación de nuestros métodos.

En el proyecto de nuestro servicio WCF creamos una nueva carpeta llamada Behaviors ya agregamos una nueva clase llamada “MyOperationBehavior.cs” con el siguiente código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace CalculatorService.Behaviors
{
    public class MyOperationBehavior : Attribute, IOperationBehavior
    {

        #region IOperationBehavior Members

        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
        {
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
        {

// Decorator pattern.
            dispatchOperation.Invoker = new MyOperationInvoker(dispatchOperation);
        }

        public void Validate(OperationDescription operationDescription)
        {
        }

        #endregion
    }

    class MyOperationInvoker : IOperationInvoker
    {
        private readonly IOperationInvoker _invoker;
        private readonly System.ServiceModel.Dispatcher.DispatchOperation _dispatchOperation;

        public MyOperationInvoker(System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
        {
            this._invoker = dispatchOperation.Invoker;
            this._dispatchOperation = dispatchOperation;
        }

        private void HandleOperationRequest(object instance, object[] inputs)
        {
            Service1 srv = (Service1)instance;
            srv.Audit(_dispatchOperation.Name, inputs);
        }

        #region IOperationInvoker Members

        public object[] AllocateInputs()
        {
            return _invoker.AllocateInputs();
        }

        public object Invoke(object instance, object[] inputs, out object[] outputs)
        {
            HandleOperationRequest(instance, inputs);
            return _invoker.Invoke(instance, inputs, out outputs);
        }

        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
            HandleOperationRequest(instance, inputs);
            return _invoker.InvokeBegin(instance, inputs, callback, state);
        }

        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            return _invoker.InvokeEnd(instance, out outputs, result);
        }

        public bool IsSynchronous
        {
            get { return _invoker.IsSynchronous; }
        }

        #endregion
    }
}

Ahora decoramos nuestros métodos Add y Substract con el atributo anterior y creamos el método “Audit”:

image

Lo que hemos hecho hasta el momento es crear una clase MyOperationBehavior que se encarga de conectar el MyOperationInvoker al servicio. Al aplicar el atributo  [MyOperationBehavior] en cada operación hacemos que WCF use nuestro Operation Invoker para llamar a las respectivas funciones.

Dentro de MyOperationInvoker estamos llamando primero al método Audit para imprimir en pantalla la operación que el usuario está a punto de ejecutar.

Esto nos da el control de poder ejecutar código adicional antes de que se ejecute el método que invocó el cliente (o incluso desués). Si volvemos a ejecutar el servicio podemos ver los resultados en la ventana “Output” de Visual Studio 2010.

image

Nota: Este mismo resultado se pudo obtener llamando desde los métodos Add y Substract al método Audit. Pero gracias a los OperationBehaviors podemos remover esta lógica de cada posible método que tengamos y ponerla en un solo lugar.

ASP.NET Web Client Software Factory

Posted in ASP.NET, Opinion, Patrones de Diseño on diciembre 8, 2008 by César Intriago

black01 Ya está disponible el primer documento sobre el Web Client Software Factory para ASP.NET, esta es una introducción al mismo.

La idea de publicar los artículos de WCSF en este formato es con el objetivo de facilitar el acceso al mismo (y también es mas sencillo escribirlos).

Los invito a comentar sobre qué les parece esta forma de poner los documentos, sugerencias y comentarios son bienvenidos. También estoy pensando retomar los temas de Blend y WPF que hace algún tiempo los tengo abandonados.

Descargar PDF

WCSF – Parte 1: Diseño de la aplicación

Posted in Aplicaciones, ASP.NET, Patrones de Diseño, Tutorial on noviembre 16, 2008 by César Intriago

En este post diseñaremos la aplicación que deseamos construir usando el Web Client Software Factory que explicamos en la entrada anterior.

La aplicación que queremos desarrollar es una página ASP.NET que permita ingresar y mostrar un lista de comentarios, el wireframe de cómo queremos que se vea nuestra aplicación es el siguiente:

04 wireframe

Con esto nos damos una buena idea de lo que queremos lograr, es algo sencillo que nos servirá para nuestro ejemplo. Una vez que tenemos la idea inicial empezamos con crear una base de datos para guardar los comentarios, a continuación el script:

CREATE DATABASE CommentsWebClient
Go

USE CommentsWebClient
GO

CREATE TABLE Comments (
    [Id]        INT IDENTITY (1,1) PRIMARY KEY NOT NULL,
    Name        VARCHAR(100) NOT NULL,
    Place        VARCHAR(100) NOT NULL,
    [Text]        VARCHAR(250) NOT NULL,
    CreatedOn    DATETIME DEFAULT (GETDATE()) NOT NULL
)
GO

CREATE PROCEDURE GetComments
AS
    SELECT [Id], Name, Place, [Text], CreatedOn
    FROM Comments
    ORDER BY CreatedOn DESC
GO

CREATE PROCEDURE AddComment (
    @name    VARCHAR(100),
    @place    VARCHAR(100),
    @text    VARCHAR(250),
    @Id        INT OUTPUT
)
AS
    INSERT INTO Comments (Name, Place, [Text])
    VALUES (@name, @place, @text)
    SET @Id = SCOPE_IDENTITY()
GO

Una vez que tenemos lista nuestra base de datos, ahora sí a lo que nos interesa.. vamos a crear nuestro proyecto en Visual Studio 2008:

En VS2008 creamos un nuevo proyecto de tipo Web Client Software, lo llamaremos “CommentsWebClient”:

01 create-project

Una vez finalizado la creación, nuestro proyecto se verá así:

02 project-structure

Como nos damos cuenta se crean de forma automática los elementos que dan soporte al patrón Model-Vew-Presenter.

Dentro de la carpeta “WebSites” de la solución está la plantilla inicial de nuestra aplicación ASP.NET, mientras que en la carpeta “Modules” se encuentran los presenters y las interfaces de cada una de nuestras vistas (las páginas .aspx). Por ejemplo la página Default.aspx posee su respectivo presenter “DefaultViewPresenter.cs” y la interfaz que implementa: “IDefaultView.cs”, pero qué significan todos estos archivo y para qué sirven?, bueno la respuesta es la siguiente:

Nuestra página Default.aspx implementa la interfaz IDefaultView, lo que significa que cualquier definición de propiedades, eventos o métodos que pongamos en la interfaz, deberá ser implementado por la página .aspx; esto es con el principal objetivo de que el presenter sepa qué métodos y propiedades está disponibles en la vista sin importarle la implementación concreta de la misma, de esta forma el presenter realiza las operaciones concretas y la vista provee de los datos de entrada necesarios. Aquí un diagrama de esta relación:

05 mvp-diagram

Por cierto el WCSF ha creado la aplicación ASP.NET con contenido de ejemplo lista para ser probada, si arrancamos nuestro proyecto podremos ver algo así:

03 test-project

Así que sin mayor esfuerzo ya tenemos una aplicación simple usando el patrón MVP, en la segunda parte de este tutorial empezaremos a escribir el código para el acceso a los datos, y Linq !! así como modificar la vista existente. Si tiene dudas sobre el WCSF o el MVP comenten y trataré de responderlas.

Web Client Software Factory

Posted in Aplicaciones, ASP.NET, Patrones de Diseño, Tutorial on noviembre 16, 2008 by César Intriago

INTRODUCCIÓN

El Web Client Software Factory (WCSF) es una colección de guías para desarrollar aplicaciones Web (ASP.NET) siguiendo el patrón Model-View-Presenter (MVP). La versión de febrero del 2008 puede ser descargada desde aquí.

De forma rápida, el patrón MVP trata de separar la vista o “view” del “presenter” y del “modelo”. La “vista” viene a ser una página .aspx, es decir la interfaz gráfica de nuestra aplicación, el “modelo” representa a nuestras clases que alamcenan y manejan datos, finalmente el “presenter” es quien se encarga de unir la vista con el modelo, en el presenter encontramos la lógica para cargar, procesar y pasar los datos, así como de leer entradas del la IU y manejarlas.

La idea básica del patrón MVP es remover de nuestros archivos .aspx e incluso aspx.cs (la vista) toda la lógica de negocio posible, y colocarla en su respectivo presenter. Además de promover el desarrollo de sistemas basados en módulos (Compsite Web) reutilizables.

En post siguientes publicaré cómo desarrollar una aplicación sencilla pero que cubra muchos puntos del uso del WCSF: Acceso a datos, creación de módulos, Control de flujo y pruebas unitarias.  Estén atentos !!.

BlackPoint – Framework

Posted in BlackPoint, Patrones de Diseño on septiembre 4, 2008 by César Intriago

BlackPoint Framework es un componente que permite desarrollar los adaptadores de contenido (módulos encargados de extraer la información de los archivos), los repositorios (módulos para persistir los datos de la aplicación), y para implementar la aplicación cliente de BlackPoint.

Precisamente este framework es el que estoy usando para desarrollador el adaptador para PowerPoint 2007, el repositorio en archivos XML y la aplicación cliente en Windows Presentation Foundation. Básicamente este framework provee:

  • Las interfaces con las que se deben programar para BlackPoint y los objetos que se pasan entre los distintos componentes de la aplicación.
  • Métodos de extensión para facilitar tareas de convertir objetos a XML y viceversa.
  • Implementaciones básicas de las interfaces para contenido.
  • Eventos para notificar al cliente sobre sucesos de los adaptadores.
  • Otros miembros de que ayudan en la implementación de los componentes.

El siguiente es un diagrama de clases del framework de BlackPoint:

BlackPoint.Framework

  • IOpenXmlPart: Representa una parte del contenido de un archivo, por ejemplo cada una de las diapositivas de una presentación se representan como una parte.
  • IOpenXmlContent:Representa un contenido en particular, por ejemplo todo una presentación en PowerPoint 2007.
  • FrameworkOpenXmlContent y FrameworkOpenXmlPart: Implementaciones concretas de las interfaces IOpenXmlContent e IOpenXmlPart, estas implementaciones se ofrecen en el framework para evitar que los desarrolladores tengan que hacerlo en sus propios adaptadores, si lo desean pueden crear también sus propias implementaciones.
  • ILibraryRepository: Cualquier repositorio de datos que se desee usar para BlackPoint debe implementar esta interfaz.Un repositorio se encarga de almacenar los datos de los contenidos, puede ser en archivos XML, bases de datos, etc.
  • IOpenXmlAdapter: Los adaptadores son los encargados de leer el contenido de los archivos y extraer sus datos, la información es cargada dentro de un objeto que implemente la interfaz IOpenXmlContent. Por ejemplo el adaptador de PowerPoint 2007 lee un paquete con extensión “.pptx” y extrae la información de Título, Autor, Descripción, Palabras claves, diapositivas y una vista previa de cada una.
  • IFileType: Permite identificar los archivos soportados por cada adaptador. Por ejemplo el adaptador para PowerPoint 2007 se usa para archivos con extensión “.pptx”.
  • ContentImportedDelegate y ContentEventArgs: Evento personalizado para notificar cuando a los subsciptores cuando un adaptador ha terminado de importar un contenido, se pasa como argumento el contenido importado.
  • Utils.GetImageStream: Lee una imagen de una Uri y la convierte a un mapa de bits en memoria.
  • Extension ToOpenXmlContent: Convierte un objeto XmlNode a IOpenXmlContent.
  • Extension ToXmlElement: Convierte un objeto IOpenXmlContent a un objeto XmlElement.
  • BlackPointSettings: Provee configuraciones generales del framework, como los nombres de los elementos para archivos XML.

Como se podrán dar cuenta, un principio básico que intento seguir es el de programar contra interfaces y no contra objetos en concreto, de esta forma se facilita la extensión del código y el soporte para nuevos módulos personalizados o especializados.

En entradas futuras publicaré mas diagramas de clases usados en BlackPoint. Como ven se han realizados algunos cambios desde la primera versión de este diagrama.

BlackPoint 2008 – Avanzado !!

Posted in Aplicaciones, BlackPoint, Blend, Errores, Patrones de Diseño, Tutorial, WPF on agosto 25, 2008 by César Intriago

Maldito Qumana!! acaba de borrar todo el contenido de esta entrada, textos, imágenes, enlaces, todo. DIABLOS, voy a tener que escribir todo el post nuevamente… y lo que ya no me acuerdo….. aarrggg…. PRRRT.

BlackPoint: Modelo de Clases v1.0

Posted in Aplicaciones, BlackPoint, Blend, Patrones de Diseño, WPF on julio 7, 2008 by César Intriago

Para conocer sobre el proyecto BlackPoint visiten el post: BlackPoint 2008 vive!

Mi primera tarea para el proyecto BlackPoint es tratar de modelar las clases que intervendrán en la solución, a continuación expongo los primeros modelos que he diagramado, estos modelos se irán puliendo y modificando con el tiempo pero creo que es un buen inicio.

Estos diagramas representan las siguientes funcionalidades:

  1. Un Adaptador recibe la dirección de un archivo en formato Open XML, este se encarga de abrirlo y empezar a leer su contenido, la información del archivo se guarda en un objeto OpenXmlContent (por ejemplo: Nombre del archivo, palabras clave de búsqueda, etc..), los datos de las partes del archivo (por ejemplo: las diapositivas de un archivo Power Point) se guardan en una lista de objetos tipo OpenXmlPart. La idea del adaptador es que trabaje en segundo plano (en otro hilo) y una vez finalizado Notifique al cliente (aplicación WPF) que el trabajo ha terminado y los datos están listos.

  2. La aplicación cliente deberá guardar la información de archivos cargados y su contenido en algún lugar como un archivo XML, texto plano o una base de datos, a esto le llamaremos el Repositorio de datos.

  3. Por ahora no nos preocuparemos de las clases concretas que implementarán cada una de las funcionalidades, nos limitaremos a definir las intefaces que usaremos.

El primer diagrama modela los Adaptadores (color verde), los tipos de archivos soportados (color kaki) los Repositorios  (color fucsia) y las Notificaciones (color celeste). Los elemetos de color amarillo son tipos del .NetFramework.

Adaptadores

  • Descripción: Encargados de abrir un paquete en formato Open XML y extraer su contenido.

  • Patrón  de diseño: Strategic Pattern

Tipos de archivos

  • Descripción: Lista de tipos de archivos que el adaptor puede abrir. Se basa en la extensión del archivo.

Repositorio

  • Descripción: Se encarga de persistir los datos de la aplicación, el objetivo es que se puedan usar distintos repositorios como archivos XML y bases de datos.

  • Patrón de diseño: Strategic Pattern

Notificaciones: Publicador/Subscriptor

  • Descripción: Registra y mantiene notificados a los clientes cuando un adaptor ha completado su trabajo de extraer infromación de un paquete Open XML.

  • Patrón de diseño: Observer Pattern

El segundo diagrama presenta dos conceptos: El primero (colo verde) se encarga de iniciar el respectivo Adaptor Open XML, usa Factory Pattern para encapsular la creación/ejecución de un Adaptor.  El segundo usa Singletone Pattern para devolver una única instancia de un repositorio de datos que será usado a lo largo de toda la aplicación.