Cadastre-se Revistas DevMedia Cursos
 

Space de Marcelo Palladino
Busca Autor


Últimas 20 atualizações de Marcelo Palladino

Artigo - WEB Services e tipos definidos pelo usuário

Web Services

WEB Services e tipos definidos pelo usuário

 

Neste artigo vamos ver como utilizar tipos próprios em serviços WEB. Utilizar tipos próprios em serviços WEB pode ser considerado por alguns, algo paradoxal. De certa maneira é mesmo. Veja a questão da distribuição. Um dos objetivos do WEB service é tornar o cliente mais fácil de distribuir. Usar tipos próprios em serviços WEB pode obrigá-lo a distribuir seus assemblies tanto no cliente quanto no servidor em um aplicativo Windows, por exemplo.

De fato, em todo tempo que trabalho com a plataforma .Net houve apenas dois casos em que precisei abrir mão deste recurso. Em ambos os casos já havia uma ampla camada de modelos baseada em tipos próprios. Tipos estes que precisavam ser utilizados nos dois extremos dos aplicativos. 

 

Mão na massa

Para começar vamos criar dois projetos. Um para o serviço WEB, que vamos chamar de CustomerService e outro para nossa biblioteca de classes que conterá nossos modelos. Vamos chamar este último de WSWithMyOwnTypes.Model. A sua solution Explorer deve estar como a da Figura 1.

 

Listagem 1. Modelagem de um cliente no projeto WSWithMyOwnTypes.Model.

using System;

using System.Collections.Generic;

using System.Text;

 

namespace Palladino.Articles.WSWithMyOwnTypes

{

    public class Customer

    {

        private string name;

 

        //Apenas estado, por enquanto

        public string Name

        {

            get { return this.name; }

            set { this.name = value; }

        }

    }

}

 

Figura 1.  Solution Explorer

 

Listagem 2. Serviço WEB simples para usar um cliente no projeto WSWithMyOwnTypes.CustomerService.

using System;

using System.Data;

using System.Web;

using System.Collections;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.ComponentModel;

 

namespace Palladino.Articles.WSWithMyOwnTypes

{

    [WebService(Namespace = "http://tempuri.org/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    [ToolboxItem(false)]

    public class CustomerService : System.Web.Services.WebService

    {

        [WebMethod]

        public string MakeSomethingWithCustomer(Customer customer)

        {

            //Apenas utiliza o estado de 'customer' para o

            //retorno do método

            return customer.Name;

        }

    }

}

Observação

  Este fragmento de código utiliza o namespace http://tempuri.org/ para o serviço. A técnica mostrada neste artigo depende desta informação, de forma que você deve dar bastante atenção a isto quando for implementar os seus próprios serviços. O código fonte usado como exemplo para este artigo utiliza o namespace http://palladino.com.br.

 

Vamos criar mais um projeto, desta vez uma aplicação Windows, para consumir o serviço CustomerService. Vamos chamar este novo projeto de

WSWithMyOwnTypes.CustomerServiceConsumer. Este projeto conterá uma referência para o serviço (Web Reference) e outra para a biblioteca de modelos. Observe a Figura 2 que representa o seu Solution Explorer

 

Figura 2. Solution Explorer

 

No formulário deste aplicativo, depois que a referência WEB tiver sido adicionada adequadamente, vamos criar um botão e manipular o seu evento Click conforme indicado na Listagem 3.

 

Listagem 3. Fazendo a chamada do serviço WEB (com erro de compilação)

private void button1_Click(object sender, EventArgs e)

{

     MyServices.CustomerService service = new

                MyServices.CustomerService();

         Customer anyCustomer = new Customer();

         anyCustomer.Name = "Um cliente qualquer";

         MessageBox.Show(service.MakeSomethingWithCustomer(anyCustomer));

}

Ao tentar compilar este código vamos receber a seguinte mensagem de erro:

The best overloaded method match for Palladino.Articles.WSWithMyOwnTypes

.MyServices.CustomerService.MakeSomethingWithCustomer(Palladino.Articles

.WSWithMyOwnTypes.

MyServices.Customer)' has some invalid arguments.

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
23/05/2008 12:09:00





Artigo - Design Patterns em formulários Windows complexos – Parte II


Design Patterns em formulários Windows complexos – Parte II

 

Um jeito diferente de fazer

Uma maneira diferente de fazer o programa usado neste artigo e aquele do qual falei no início é utilizar padrões de projeto (design patterns). Padrões de projeto são soluções simples para problemas específicos. Não exigem nenhuma característica especial da linguagem e têm o objetivo de tornar os programas mais flexíveis e reutilizáveis. O padrão que, em minha opinião, se encaixa melhor para interfaces complexas é o Chain of Responsability (cadeia de responsabilidades).  Ele tem o objetivo de evitar o acoplamento entre aquele que envia uma solicitação e aquele que a recebe. Apenas para exemplificar, no programa que citei antes, seria mais ou menos o seguinte:

  • Quando um indicador é modificado ele “envia uma mensagem” dizendo: Olá, sou o indicador X e fui alterado da maneira Y;
  • Aqueles que são afetados por esta modificação “tratam” esta mensagem de maneira apropriada.

Para usar este padrão em interfaces com usuário eu fiz algumas adaptações que somadas têm o seguinte aspecto:

 

mpdpfwcp1fig05.jpg 

 

Uma questão de nomenclatura: O padrão cita aqueles que podem manipular uma requisição como manipuladores (handlers) e aqueles que iniciam uma requisição como clientes (clients). Do ponto de vista do formulário todos podem iniciar e tratar uma requisição. Desta forma, eu escolhi chamar todos os participantes de ‘partes’ (parts). As requisições que podem ser feitas pelas partes são chamadas aqui de mensagens (messages) e a classe que controla como uma mensagem chega até todas as partes é chamada de gerenciador de mensagens (MessageManager).

 

Para ser parte participante do padrão uma classe deve implementar a interface IMessageManagerPart. Esta interface define se a parte contém subpartes e disponibiliza um método chamado ReceiveMessage que servirá para interceptar e tratar as mensagens enviadas pelo gerenciador de mensagens.

 

Um código típico para criação de uma nova parte é o seguinte:

 

public partial class DummyPart : UserControl, IMessageManagerPart

{

        private MessageManager messageManager = null;

        private IMessageManagerPartCollection subparts = null;

 

        protected DummyPart() : base()

        {

               InitializeComponent();

        }

 

        public DummyPart(MessageManager messageManager) : this()

        {

               this.messageManager = messageManager;

        }

 

        #region IMessageManagerPart Members

 

        public IMessageManagerPartCollection Subparts

        {

               get { return this.subparts; }

        }

 

        public MessageManager Manager

        {

               get { return this.messageManager; }

        }

 

        public bool ReceiveMessage(ref ImessageManagerMessage message)

        {

               return false;

        }

 

        #endregion

}

 

Uma vez definidas as partes que estarão na sua interface, será necessário começar a pensar nas mensagens que serão utilizadas por estas partes. Para criar uma mensagem será necessário utilizar a interface IMessageManagerMessage:

 

public class CloseRequested : IMessageManagerMessage

{

        #region IMessageManagerMessage Members

 

        public bool AllowMultipleHandler

        {

               get { return false; }

   &nb

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
27/08/2007 15:03:00





Artigo - Design Patterns em formulários Windows complexos – Parte I


Design Patterns em formulários Windows complexos – Parte I

 

Introdução

A seis anos eu trabalhava com Delphi em projetos de outsourcing. Gostava do trabalho, pois tinha oportunidade de, a cada projeto, conhecer pessoas novas em ramos de atividade quase sempre diferentes. Por outro lado, algo que me incomodava muito era a falta de tempo dedicado a pensar no que era feito. Hoje, quando penso nisso, vejo que o foco era fazer funcionar para cumprir o prazo.

 

Um dos projetos que mais me recordo desta época é o de um software que seria utilizado para controlar transações financeiras de uma corretora. Esta corretora controlava os investimentos de centenas de clientes. Regras de negócios à parte, o mais interessante deste projeto era o fato de que ele deveria possuir um dashboard que serviria como uma espécie de painel de alertas. Reza a lenda que na especificação original deste painel havia palavras como mediúnico e sagrado. Mas esta especificação eu não vi...

 

Em última análise este dashboard era um formulário que deveria funcionar como uma espécie de painel de carro, emitindo avisos conforme a situação atual. Eis algumas características que constavam na especificação final:

·         O usuário deve ter a liberdade de ‘montar’ o painel da forma como bem desejar;

·         Adicionar um novo indicador deve ser o mais simples possível (do ponto de vista de programação e do ponto de vista de usabilidade);

·         Ao alterar um parâmetro do painel, os indicadores que forem afetados devem ser atualizados.

 

Hoje vejo que o mais próximo do ideal seria que nós fizéssemos as partes deste formulário com o mínimo de acoplamento possível umas com as outras. Um indicador não deveria conhecer todas as partes afetadas por uma modificação realizada nele, por exemplo.

 

Pois bem, isto seria o ideal, mas não foi o que fizemos. Para tornar curta uma história que é longa vou dizer o seguinte: Nós fizemos o programa, levamos cerca de nove meses para construí-lo, ele roda até hoje e atualmente é um exemplo para mim. Um exemplo do que não deve ser feito! O tal formulário do dashboard hoje está com cerca de 30 mil linhas e é um bloco monolítico (eu já vi programas Clipper melhores estruturados). Veja bem, eu estou falando de uma classe com milhares de linhas, centenas de métodos e com centenas de agregações que conhece todos (eu disse todos) os detalhes imagináveis da operação do dashboard.

 

A situação era tão grave que manter aquele programa era quase como isto:

·         Cliente paciente: Doutor, meu braço dói;

·         Desenvolvedor residente: Deite aqui, por favor. Vou aplicar uma anestesia geral;Cliente paciente: O que?! Eu só estou com dor no braço! Tire a mão de cima de mim...;

·         Desenvolvedor cirurgião: Bisturi, por favor...

 

Brincadeiras à parte, o que aconteceu naquela ocasião foi que pensamos na interface como algo feito em camadas, não como uma classe. Minha teoria é que com o advento da programação “orientada a eventos” sugerida pelo modelo de desenvolvimento RAD, alguns programadores (como nós na época) “esqueceram” que formulários são classes. Para piorar, neste caso específico o formulário tinha de suportar alterações de uma maneira melhor do que simplesmente sair colocando “if” (e bota if nisto) nas rotinas existentes.  Bem, o “jeito” encontrado para fazer aquilo pode ser resumido da seguinte forma:

 

1-Colocávamos um monte de painéis no formulário.

 

2-Conforme a ação que usuário escolhesse, controlávamos as propriedades Visible destes painéis e, às vezes, até de controles dentro deles.

 

3-Todo mundo conhecia todo mundo. Um indicador sabia quem ele teria de afetar.

...
Exibição do post interrompida. Para ler conteúdo completo, clique aqui
27/08/2007 15:00:00





 

Marcelo Palladino (marcelopalladino@uol.com.br), trabalha profissionalmente com desenvolvimento à 16 anos. Neste período participou de projetos em empresas como Banco do Brasil, Embratel, Banco Safra, Rede Globo entre outras. Atualmente atua como desenvolvedor no grupo Sonda IT.
Arquivo de atualizações
 2008
 2007

Estatísticas do Autor:
Número de posts: 7
Características dos posts deste autor:
Conteúdo:
Utilidade:
1 0
 
DevMedia Group - Tel: (21) 3382-5038 - www.devmedia.com.br
Todos os Direitos Reservados a DevMedia Group