Introdução

Este artigo visa demonstrar como o uso de serviços em aplicações .NET podem te ajudar a criar aplicações distribuídas modernas.

Para uma idéia de como funcionam aplicações web modernas, veja o artigo anterior que mostra como criar começar a organizar a sua solução para começar a trabalhar.

Vamos falar sobre Web Services, Windows Communication Foundation, configurações típicas para sistemas Web e aplicações distribuídas. Vamos também falar um pouco sobre as tendências da Microsoft para a exposição de dados na forma de serviços modernos.

Onde Estamos?

Você criou uma aplicação Web. Ela entrou em produção na sua empresa. Você ganhou reconhecimento e notoriedade no ambiente de trabalho devido ao aumento de velocidade na obtenção de métricas. Muitos ficaram sabendo que as informações que o seu sistema gera são confiáveis. Outras áreas concorrentes viram outras oportunidades de redução de custos operacionais. Um e-mail chega:

“Olá! Nós precisamos muito de sua ajuda! O sistema ABC que você criou está nos economizando muito tempo, porém, ainda tenho que fica digitando o resultado dos seus cálculos no sistema XYZ que você criou no ano passado… Não tem como você fazer com que os dados apareçam automaticamente?”

Atualmente o sistema se apresenta para o cliente no formato Web clássico. Ele é muito útil, porém, é útil para seres humanos compreenderem as informações. Entretanto, outro sistema não consegue entender e processar os dados gerados nos seus relatórios. E agora o que fazer?

Para você que já está no mercado, a solução é quase óbvia: por que não usar Web Services?

Web Services

Web Services são lugares públicos conhecidos na rede (na internet, intranet, porta tcp local) que são capazes de expor uma informação com base num pedido. No caso acima, o sistema XYZ, que usa os dados do sistema ABC, deveria fazer uma requisição ao Web Service hospedado em algum endereço conhecido do sistema ABC. O sistema ABC recebe a requisição e dá a resposta em um formato combinado entre as partes.

Aí você que está começando pode se perguntar: “Não entendi bem, afinal, qual é a diferença entre um site normal da Web e um Web Service?”. A resposta prática para esta questão é a seguinte: um site comum da web retorna tudo o que pode aparecer no browser, como imagens, HTML, animações e demais itens. O Web Service funciona da mesma forma, usando os mesmos protocolos de rede e os mesmos caminhos, mas retorna apenas, no caso geral, um XML contendo os dados de interesse. Ambos possuem um endereço na internet/intranet. Neste exemplo, é possível ter o site, www.abc.suaempresa.com.br para hospedar o site correspondente ao sistema ABC. Para hospedar o Web Service do sistema abc, seria possível criar um endereço na intranet de nome www.abc.suaempresa.com.br/webservice.

Assim como browsers conseguem ler HTML, sistemas feitos .NET, Java e demais linguagens conseguem traduzir tudo o que está exposto no Web Service e com isso, conseguem se comunicar com o mesmo. Existe um protocolo padrão da indústria para a comunicação utilizando Web Services, que é o SOAP. Ao definir um Web Service, podemos definir as operações (posso receber comandos) e posso definir o tipo de dados o Web Service utiliza (por exemplo, podemos definir entidades complexas como por exemplo, a classe Pessoa). Também é possível definir outros parâmetros diversos, como a obrigatoriedade de certos parâmetros/valores, etc..

O processo de “tradução” do conteúdo de um Web Service geralmente é automático em todas as tecnologias da atualidade – inclusive em .NET. O Visual Studio consegue ler o que está no Web Service e gerar métodos e classes “proxy", que imitam o que o serviço faz dando a impressão para o desenvolvedor de que a chamada de um certo método é local.

Em várias plataformas de desenvolvimento, a comunicação entre sistemas utilizando Web Services é a forma padrão de se integrar sistemas diversos. E quando falamos de integração entre sistema de diversos fornecedores com diversas tecnologias, a forma mais simples de se conseguir uma integração é utilizando Web Services mesmo. Porém, para os desenvolvedores que utilizam a plataforma .NET., esta tecnologia é considerada obsoleta a partir do surgimento do .NET Framework 3.0 e 3.5, que trouxeram e consolidaram no mercado uma maneira mais completa de se trocar dados entre sistemas que rodam em Windows: Windows Communication Foundation.

Windows Communication Foundation

A Microsoft sempre disponibilizou para seus desenvolvedores um grande conjunto de opções para realizar quase sempre árdua tarefa de fazer 2 sistemas trocarem dados entre si. Com o advento do WCF, a Microsoft unificou e simplificou todos os tipos de tecnologias numa única tecnologia mais completa, simplificada e muito madura no momento da escrita desde post, Janeiro de 2010.

Com o WCF temos algumas boas vantagens:

  • Não somos obrigados a comunicar utilizando SOAP via HTTP
  • Qualquer aplicação pode ser servidor para o WCF, isto é, não preciso de um servidor Web para nenhum tipo de tarefa
  • Posso contar com recursos do Windows para ativar o serviço com a chegada de uma nova mensagem
  • Temos grande liberdade para determinar como será a passagem de mensagens de um lado para o outro. Temos controle sobre a segurança, formato das mensagens, transações, confirmação de recebimento de uma mensagem, filas de mensagens e também, podemos interferir diretamente sobre a mensagem recebida ou enviada. Podemos ter comunicações em 2 sentidos, coisa que nem sempre é fácil de ser implementada.
  • Flexibilidade para configurar o serviço, muitas vezes, evitando que qualquer linha de código seja escrita.
  • Não é necessário aprender Remoting, COM+, Enterprise Services, etc… – basta aprender o conceito de Web Services e o WCF em si.

Na prática, a maior parte das pessoas utilizam e utilizarão WCF para trocar mensagens SOAP via HTTP. A grande vantagem que vemos no uso do WCF é a possibilidade de se criar um projeto “Windows Service” (*.exe) para hospedar o meu serviço em WCF. Com isso, ganha-se a possibilidade de controle total, ainda mais quando o sistema tem chances de cair. Um serviço WCF hospedado no IIS, em alguns casos, pode ser prejudicial em caso de falha. Mas cada situação é diferente e para cada caso é necessário realizar uma análise completa da arquitetura para enfim decidir a melhor forma de hospedagem.

Qualquer tipo comum de projeto pode hospedar o WCF e quase qualquer tipo de aplicação .NET consegue fazer referência a um servço existente. Até mesmo aplicações como Office, Silverlight e Sharepoint trabalham bem com WCF.

Camadas de serviços modernas

Para o caso de aplicações atuais, o WCF é peça fundamental na arquitetura de um sistema orientado a serviços ou mesmo, para aplicações distribuídas.

Utilizando um mesmo serviço (ou conjunto de serviços) você pode fazer com que o sistema atenda a diversos tipos de clientes tais como Windows, Web, Celulares, Aplicações RIA (Flash / SIlverlight), Office, etc… Todos eles conseguem se conectar à mesma fonte de informação de forma uniforme, centralizando num único ponto as fontes de dados e possivelmente, de regras de negócio da aplicação como um todo.

Ao adicionar um serviço à solution do Visual Studio, você está na prática adicionando uma camada de serviços à sua aplicação. Como já falamos anteriormente, é preciso ter atenção e evitar qualquer camada desnecessária interferindo no fluxo de dados principal da aplicação. Mas, após as devidas análises terem sido feitas, você estará construindo uma aplicação com a possibilidade de ser distribuída, isto é, você ganha a capacidade de criar vários clientes para acesso dos mesmos dados. No caso de aplicações RIA, não há outra forma de se fazer acesso a dados sem ser por intermédio de uma camada de serviços, por questões de segurança da Web.

Consideramos como moderna uma camada de serviços criada sem restrições quando à forma de hospedagem, forma de lidar com as mensagens e principalmente, com a forma de passar os dados pelo “channel” ou canal de informações. Em .NET, somente o WCF consegue oferecer este tipo de capacidade para o desenvolvedor. Com o uso de WCF, o cliente pode referenciar o serviço da mesma forma que é referenciado um Web Service hoje em dia.  Porém para ser moderna a camada de serviços também precisa ser capaz de expor os dados de forma atualizada. Isto significa que os serviços de “hoje em dia” devem expor os dados em formato REST também. Outra funcionalidade também é a utilização de dados em formato JSON, XML e mesmo, serializados conveniente de forma binária para otimização de banda. O WCF possui tecnologia para endereçar todos estes requisitos. A Micrososft está adotando o padrão de acesso e manipulação de dados OData (Open Data Protocol), que basicamente uniformiza a forma de acessar e recuperar dados entre as diversas fontes de dados da internet de hoje em dia.

Tecnologias que devemos considerar para criar camadas modernas de serviços

 

Entity Framework

O EF foi lançado na versão 3.5 SP1 do .NET Framework. Ele é voltado para acelerar e mesmo, revolucionar aplicações que utilizam o banco de dados SQL Server. Como uma ferramenta ORM, ele evita que seja necessário criar um camada de acesso a dados formal para fazer operações do dia-a-dia. O EF gera um modelo de dados que é então utilizado pelas aplicações que o utilizam para realizar consultas utilizando o LINQ para gerar consultas diretamente ao modelo. Com esta consulta ao modelo, o EF gera o SQL e retorna / modifica os dados desejados. É possível utilizar stored procedures dentro do modelo de dados.

O EF no .NET Framework 4.0 está foi radicalmente melhorado, com suporte a cenários n-camadas melhorado e com muito mais funcionalidade para auxiliar os desenvolvedores a gerar modelos de dados customizados, lazy loading, suporte a entidades simples (sem o overhead do controle de alterações do EF) e ampliado suporte a mapeamento em cenários mais complicados que foram sugeridos pelos clientes. E finalmente, será possível desenhar primeiro o modelo de entidades da aplicação para então gerar o banco de dados correspondente, coisa que é possível com o NHibernate há tempos.

A grande desvantagem na época da escrita deste artigo, Janeiro/Fevereiro de 2010, é que não há providers gratuitos para quem trabalha com Oracle, Postgree e MySQL ainda. O que se sabe é que há chance de surgir um provider gratuito para MySQL. Há empresa que oferecem providers pagos, mas não conhecemos ninguém que utilize os mesmos (por favor me corrijam se eu estiver errado).

O Entity Framework é a tecnologia base para tecnologias que também utilizam o WCF como transporte, a saber: WCF RIA Services e o WCF Data Services.

WCF Data Services (antigo ADO.NET Data Services)

O Data Services serve para expor um modelo de dados do Entity Framework através de uma interface REST. O DS é uma extensão do WCF (isto é, pode ser hospedado como qualquer serviço WCF). É uma tecnologia que visa facilitar o acesso a dados tanto de aplicações Web comuns como AJAX, como Silverlight e .NET.

Para expor os dados via WCF Data Services, é preciso que se tenha uma fonte de dados que suporte consultas utilizando LINQ, isto é, que implemente IQueryable/IUpdatable. Resumidamente, a aplicação pede um endereço para o serviço, e este endereço é traduzido como uma consulta LINQ para que então, o provedor de dados retorne os dados de interesse.

Na prática, o DS serve para facilitar muito a vida de quem programa e cria serviços usando WCF. Com o WCF puro, é possível fazer tudo. Com o Data Services, temos uma facilidade muito maior para manipular os dados de forma que não seja necessário invocar métodos específicos para atualizar cada entidade do modelo de dados. E na prática, esta facilidade é conseguida criando um modelo de dados com o Entity Framework e expondo-o com o WCF Data Services.

Esta tecnologia, existe há mais de 2 anos, está evoluindo bastante e virá com novas features como por exemplo, paginação e ordenação via servidor. Considera-se que para que seja o padrão dos desenvolvedores ainda há um caminho a ser percorrido.

WCF RIA Services

O RIA Services é uma tecnologia que surgiu com o Silverlight 2 para simplificar o acesso das aplicações feitas em Silverlight a um serviço WCF. Por segurança, as aplicações RIA (Flash e Silverlight) só podem acessar um serviço caso o mesmo esteja no mesmo domínio da aplicação web que hospeda a aplicação RIA.

Uma aplicação web hospeda a aplicação Silverlight em um domínio. Geralmente o serviço não está no mesmo projeto da Web, isto é, está em um outro projeto, ou mesmo, outra solução do Visual Studio. Neste caso é preciso que o serviço permita que a aplicação Silverlght o acesse utilizando um arquivo de permissões (crossdomain.xml e/ou clientaccesspolicy.xml, por exemplo). Isto é, o servidor onde mora o serviço do WCF a ser acessado precisa ter estes arquivos configurados.

Com o uso do RIA Services, consegue-se um middle-tier de modo que o serviço acabe ficando no mesmo domínio da aplicação Silverlight. Mas esta não é a única vantagem. A tecnologia é muito semelhante ao WCF Data Services. É possível disparar do cliente queries usando LINQ, processar e retornar os dados definidos em um modelo de dados do Entity Framework. Com o RIA Services, o desenvolvedor Siverlight consegue quase tudo o que precisa para entregar um projeto e coloca-lo rapidamente no ar. Ele possui facilidades como paginação, ordenação, filtragem, validação, coisas que facilitam muito para o desenvolvimento.

O RIA Services é destinado quase que exclusiva ao uso de clientes Silverlight e por enquanto não houve a convergência com o Data Services. Mas a intenção da Microsoft parece ser o investimento no ecossistema de tecnologias destinadas a serviços da web, pois afinal, a web está mais focada em serviços do que nunca.

Opções de projeto com o Visual Studio

Uma das grandes vantagens de se usar o WCF quando você criar a solução completa, isto é, os clientes e os serviços, é que você pode compartilhar bibliotecas entre as diversas camadas. Esta possibilidade permite que você use as mesmas classes do serviço, no cliente. Ou seja, a entidade “Pessoa” é sempre definida na mesma dll, que é chamada tanto de uma aplicação web como de um serviço WCF. Isto pode ser bom em situações onde o domínio é mais rico e contém métodos, herança e demais complicadores que podem não ser corretamente expostos pelo serviço em si.

Porém, este tipo de técnica é mais benéfica em aplicações web do que em aplicações mais ricas, como WPF, Windows e Silverlight. O grande problema de compartilhar os objetos de negócio é a necessidade de distribuição das dlls todas as vezes que a versão muda. E para aplicações distribuídas, é recomendável manter a regra de negócios no lado do serviço já que todo o código que roda no cliente pode ser de alguma forma visto e pode sofrer processo de engenharia reversa. Numa aplicação ASP.NET, a lógica da aplicação ainda fica no servidor, impedindo que a lógica da aplicação circule pela internet, vindo para o cliente apenas código Html/CSS e Javascript.

Com o surgimento do Entity Framework, surgem novas opções de projeto. Podemos simplificar as coisas de modo que a Solution do Visual Studio fique flexível para atender a diversas situações.

Vamos propor aqui uma solução mais purista na parte de serviços. Desta forma, vamos evitar dependências com tecnologias que ainda estejam mudando, como é o caso do WCF RIA Services e do WCF Data Services. Vamos utilizar o Entity Framework como tecnologia de acesso a dados, e vamos também, propor alguns clientes que fazem acesso à camada de serviços.

Vamos lá!

Camada de acesso a dados:

Não será necessário criar a camada de acesso a dados de forma clássica. O Entity Framework expõe ao modelo de dados para as camadas de negócio e assume a responsabilidade de invocar a infraestrutura do ADO.NET (e por conseguinte, tabelas,views e procedures do banco de dados SQL Server 2005/2008). Vale lembrar ao usar Oracle ou outro banco de dados, faz mais sentido usar outra ferramenta como o NHibernate. O mesmo vale para aplicações multi-banco de dados. Há a opção com do LINQ to NHIbernate, que pode ser uma boa saída para manter os benefícios de se usar LINQ contra o modelo de dados mapeado pelo NHibernate.

Camada de negócios:

Nesta proposta de separação de camadas, vamos simplificar um pouco as coisas. Como já vamos utilizar o Entity Framework para fazer o acesso a dados, vamos centralizar na mesma biblioteca as regras de negócios e as entidades da aplicação. As entidades do sistema são as mesmas geradas pelo EF. Caso o modelo de dados não forneça todas as propriedades necessárias, ou caso seja necessário adicionar métodos às nossas entidades geradas pelo modelo, iremos utilizar classes parciais para complementar as entidades da aplicação.

Na mesma dll mas em pastas diferentes, poderemos definir as regras de negócio e algumas classes utilitárias. Claro que para projetos maiores e mais complexos pode fazer sentido quebrar essa camada de negócios em mais bibliotecas.

Vale ressaltar aqui que, com o lançamento do EF do .NET 4.0, você tem a capacidade de controlar o mapeamento e a geração de classes automática do EF, permitindo que se use modelos de dados cada mais inteligentes nos mapeamentos. Também será possível criar o banco e dados a partir da definição do modelo de dados, tudo isso de dentro do Visual Studio.

Camada de serviços:

Vamos utilizar a camada de serviços como o ponto de encontro da nossa aplicação. Ela acessará a camada de negócios, fazendo o meio-de-campo entre os dados do servidor e as solicitações dos clientes diversos, que acessarão o serviço WCF. Neste projeto, vamos pensar numa arquitetura mais robusta e portanto, vamos hospedar o serviço em um Windows Service, para ter total controle sobre o que acontece com o serviço. O IIS7 possui várias funcionalidade interessantes para a parte de serviços, mas nossa experiência mostra que quando o serviço está propenso a erros ou quando ele exige uma quantidade maior de memória e processamento, o servidor Web pode não ser o host mais adequado. Porém, como muitos de nós utiliza hospedagem compartilhada, a hospedagem em IIS pode ser a única opção.

Clientes: ASP.NET, Silverlight e WPF

Os clientes poderão fazer referência direta apenas ao serviço neste modelo de solução proposto. Eles não poderão ter acesso a mais nenhuma dll das camadas acima. Para a utilização de Silverlight em aplicações de negócios, recomenda-se também o padrão de projetos MVVM, que busca criar aplicações mais testáveis e com lógica de negócios mais separada possível da lógica de apresentação.

Para o caso de aplicações ASP.NET clássicas ainda acreditamos que faz sentido criar uma DLL compartilhada entre o serviço e a Web. Neste caso específico, não temos grandes problemas com deploy e local de armazenamento da regra de negócios no caso simples, onde o serviço e a web estão na mesma solution e fazem parte do mesmo processo de Deploy.

Conclusão

O uso de WCF ainda está sendo descoberto pelas empresas não só do Brasil, mas do mundo. Há muita coisa pronta feita em Web Services “normais” do .NET e inclusive, novos projetos ainda hoje são criados são criados usando esta tecnologia considerada legada pela Microsoft, mas não ainda pelo mercado. O grande argumento para a não migração é a falta de pessoal capacitado para utilizar esta nova tecnologia. Entretanto, é preciso que os arquitetos connheçam esta importante opção de projeto principalmente, quando o simples não é o suficiente para uma determinada situação.

Para nós da Accendis, o uso de WCF é mainstream nos projetos em que atuamos e consideramos que esta é a tecnologia base para várias inovações da Microsoft em um horizonte de 1 a 3 anos.

, , , ,
Adicionar aos Favoritos BlogBlogs Adicionar esta notícia no Linkk

Introdução

Este artigo visa demonstrar alguns conceitos básicos para você que está começando a trabalhar profissionalmente com .NET e se encontra no seguinte momento da carreira: “Vou começar um projeto do zero, qual é a melhor forma de se trabalhar?”

Vamos apresentar alguns tópicos interessantes sobre o conceito de camadas e noções de arquitetura de sistemas empresariais comuns. Vamos discutir de forma simplificada como os conceitos se relacionam, para que de fato, você consiga ter um norte para começar a desenvolver um projeto. E por fim, vamos demonstrar como tudo isso acontece organizando os projetos no Visual Studio 2008. No final do artigo temos o exemplo completo para download.

Conceitos Iniciais: Perguntas e Respostas

  1. Ouço muito falar em desenvolvimento n-camadas. Mas exatamente o que são camadas?
    É praticamente um consenso no mercado a separação do software em camadas. Para saber quais são as camadas físicas da aplicação, basta fazer a seguinte pergunta: “Em quais máquinas meu sistema irá rodar?”. Como respostas comuns, a vasta maioria das aplicações em .NET rodam em um servidor Web com o auxílio de um servidor de banco de dados. Portanto, temos 3 camadas físicas rodando em 2 máquinas: Apresentação (servidor web), Regras de negócio (servidor web) e Persistência (servidor de banco de dados e servidor web).

    Outras correntes de pensamento julgam que o número de camadas é proporcional ao número de componentes que podem rodar independentemente. Por exemplo, no caso acima, se tivéssemos também um Windows Service com o qual a parte web se comunicasse, teríamos uma quarta camada. Mesmo que o serviço rode na máquina da web.  Ou seja, na prática, o que vale mesmo é o número de “pedaços de software independentes” que fazem alguma coisa. Podemos dizer que a camada de negócios é independente pelo fato que ainda é possível rodar apenas a lógica de negócios sem a necessidade da camada de apresentação através de técnicas simples como testes unitários, por exemplo.

    Camadas lógicas são grupos de funcionalidade geralmente reutilizáveis, mas que não conseguem rodar dentro de um contexto isoladamente. Por exemplo, podemos falar em camada de acesso a dados: tal camada lógica pode ser chamada de um serviço do WCF, de uma aplicação Web clássica ou então, de uma aplicação Windows comum. Uma camada física pode conter várias camadas lógicas. Por exemplo, a camada de negócios pode conter uma camada de regras de negócio, outra camada de controle de segurança, etc…  Mas necessariamente estão no fluxo de dados principal da aplicação.

    Resumindo, camada é todo o “pedaço de software” que participa do fluxo de dados principal da aplicação. Caso o “pedaço de software” não participe mandatoriamente do fluxo de dados principal, mas é sempre utilizado de alguma forma, provavelmente estamos em vista do que chamamos de componente.

  2. O que são componentes na prática?
    Componentes são conjuntos de classes e funções agrupados por funcionalidade similar, que podem servir a qualquer tipo de propósito e podem ser chamados por qualquer outra camada, componente ou mesmo, várias camadas e componentes. Geralmente  os componentes são pensados com o reuso em mente. Inclusive, geralmente vemos que as empresas se preocupam mais em criar componentes do que camadas reutilizáveis. Na prática, ao criar uma camada de acesso a dados, não temos como reutilizar em outro projeto totalmente diferente. Porém, um componente de controle de exceções ou componente de envio de e-mail é sempre reutilizável.
  3. O que são aplicações corporativas na prática
    Aplicações corporativas são aquelas onde a sua razão de existir se justifica pela real necessidade de resolver um problema da empresa. Simples assim. Ela serve para otimizar algum processo interno, podendo ter uma criticidade alta e também, podendo ser responsável por causar grandes prejuízos à empresa caso ela não esteja no ar. Podemos afirmar que na prática, todas as aplicações corporativas trabalham com banco de dados em algum momento. Aplicações não-corporativas são aquelas que na prática são úteis apenas para uma pessoa e não para um conjunto de pessoas ou então, no caso de jogos, servem para diversão. Tais aplicações podem ser muito mais complexas ou muito mais simples do que aplicações corporativas e quase sempre são pensadas de formas totalmente distintas de uma aplicação corporativa.

Cuidados importantes

O desenvolvimento em múltiplas camadas exige que o desenvolvedor/arquiteto tenha muito senso de organização. Nós da Accendis já presenciamos vários equívocos. Vamos a eles:

  1. Não exagere no número de camadas! Utilize o mínimo de camadas necessário para que a aplicação funcione hoje e amanhã, quando for preciso criar novas funcionalidades. Quanto maior o número de camadas, maior será a lentidão da aplicação, pois os dados deverão atravessar mais obstáculos do que o necessário.
  2. Não tenha medo de separar em camadas! Há uma grande quantia de sites que usam apenas um projeto Web para fazer tudo do sistema. Tudo! Outras equipes usam o mesmo Windows Service (.exe) para colocar todas as regras de negócio do sistema, tornado-o impossível de debugar. O maior erro dos desenvolvedores é não pensar na testabilidade do código, isto é, provar de jeito simples que o código funciona. E depois, o Visual Studio é bem prático para se trabalhar com vários projetos. Como outras vantagens, temos maior clareza e organização, e no caso onde há controle de versão, quanto maior o número de arquivos e projetos, mais divisíveis são as tarefas.
  3. Evite adotar padrões de projeto prontos que são facilmente encontrados na web. Não é por que parece ser lindo usar alguns tipos de elementos de arquitetura que você realmente precisará usar. O exemplo mais clássico disso é o fato de se usar uma camada de regras de negócio que na prática, só serve pra chamar a camada de acesso a dados.
  4. Não confunda os papéis das camadas! Evite colocar regras de negócio nas páginas de code-behind. Evite colocar nas regras de negócio componentes que podem ser reutilizáveis… Enfim, use o bom senso!
  5. Use e abuse do conceito de Namespaces. Separe classes similares em pastas. Esta dica é especialmente importante para código VB.NET, onde a lógica de namespaces é confusa para os recém-chegados.
  6. Geralmente se cria 01 projeto para cada camada lógica da aplicação. Não se recomenda juntar camadas num mesmo projeto (isto é, uma DLL com mais de uma função geral). Não se recomenda também criar vários projetos para um propósito similar.
  7. Cuidado ao utilizar padrões novos/avançados de projeto, como por exemplo, inversão de controle, arquitetura de plugins ou suporte a script. Use tais recursos somente se for absolutamente necessário e se todos os riscos de fracasso estiverem controlados. O mesmo vale para arquiteturas Web 2.0, como RIAs, MVC, etc… Atualmente, a escolha da tecnologia da camada de apresentação acarreta em alterações profundas na arquitetura do sistema com um todo. O fluxo de dados se modifica radicalmente. O maior risco é a falta de conhecimento dos desenvolvedores, que já são obrigados a absorver as novidades tecnológicas em uma velocidade estonteante. Mas, sempre esteja informado sobre novidades arquiteturais, pois as mesmas podem causar uma drástica redução da carga de trabalho. Um grande exemplo é o uso do Entity Framework ou NHibernate.
  8. Refactoring não é crime! Não tenha medo de alterações grandes no seu projeto! Projetos são feitos para resolver o problema do business. Como o problema a ser resolvido pode mudar com o tempo, seu projeto e sua arquitetura também podem ser influenciados. Por exemplo, podemos ter uma página da web com alguma funcionalidade que precise também estar presente em aparelhos móveis. Obviamente as mudanças são necessárias no número de camadas, nas formas de trocas de mensagens, etc. Outro exemplo pode ser a remoção de uma camada de acesso a dados antiga feita em ADO.NET clássico para evoluir com o LINQ ou NHibernate. Outras vezes, você ser surpreendido com a necessidade de suportar mais de um banco de dados na mesma aplicação. As coisas mudam. Não seja resistente a mudanças. Aproveite!

Arquitetura básica de um projeto Web em ASP.NET

Os projetos web de hoje em dia são relativamente complexos. E projetos de grande porte geralmente acompanham serviços, executáveis e demais acessórios para realizar tarefas diversas que não sejam apenas respostas a requisições da Web.

Porém, de alguma forma tais aplicações estendem ou imitam o padrão. Basicamente, quando se usa .NET, a receita de bolo é a seguinte, mas não necessariamente a mais “profissional” ou “correta”:

  1. [Camada de apresentação] Crie um projeto do tipo “Web Application” no Visual Studio. Não crie o projeto como “Web Site” pois esta decisão acarreta em várias dificuldades em criar funcionalidade comum a todas as páginas e causa dificuldades grandes ao referenciar dlls de outros projetos.
  2. [Camada de negócios] Para a camada de negócios, geralmente se cria um projeto do tipo “Class Library” para conter regras de negócios e outra “Class Library” para conter as entidades da aplicação. Portanto devem ser criados 2 projetos. Vale relembrar que os projetos do tipo “Class Library” são bibliotecas que quando compiladas viram DLLs comuns.
  3. [Camada de acesso a dados / Persistência] No mínimo sua aplicação terá que acessar os dados de alguma forma. Os dados podem ser expostos pelo banco em forma de tabelas, views ou stored procedures. Para isso, você terá que escrever ou usar outra solução que automatize o processo de criação de métodos para se comunicar com o banco. Crie um projeto do tipo “Class Library” para o projeto de acesso a dados também.
  4. [Componentes] Crie uma biblioteca de componentes utilitários. Este projeto deverá conter componentes úteis para todas as camadas. No caso real, pode haver mais projetos de componentes.
  5. [Testes Unitários] Crie uma biblioteca para guardar testes unitários. Para isso, é preciso ter alguma versão do Visual Studio que suporte a criação de testes unitários ou então, usar o NUnit para criar os testes.

Com isso, vamos acabar com uma solution com 6 projetos, ainda isolados entre si. Vamos discutir sobre como referenciar os projetos dentro da solution.

  1. Todas as camadas devem referenciar a DLL de entidades da aplicação.
  2. O projeto de testes unitários deverá referenciar todos os projetos da aplicação, com exceção do projeto Web.
  3. O projeto Web referencia a DLL de negócios.
  4. O projeto de negócios referencia a DLL de acesso a dados.
  5. Todos os projetos, inclusive o de testes unitários, poderão referenciar a DLL de componentes, à medida da necessidade.

O diagrama conceitual da Solution do Visual Studio fica com o mostrado nas figuras abaixo. Como nós da Accendis já passamos por vários projetos em várias empresas, uma das tendências que encontramos foi a nomenclatura em inglês de namespaces, classes e métodos. Mas na prática, muitas pessoas acabam misturando as nomenclaturas para que o nome fique o menor possível. O maior argumento para usar nomenclatura em inglês é o fato de haver chances de vender o sistema para algum comprador internacional, tendo como premissa que o cliente final deverá ter condições de manter o código.

Na imagem abaixo estão os detalhes de cada projeto a ser criado:

Lista de todos os projetos a serem criados no Visual Studio

Lista de todos os projetos a serem criados no Visual Studio

Nesta imagem abaixo, podemos ver um desenho mostrando as dependências entre cada projeto:

Relacionamento entre os diversos projetos da Solution do Visual Studio

Relacionamento entre os diversos projetos da Solution do Visual Studio

Conclusão

Com esta noção inicial de como organizar um projeto, como referenciar projetos e soluções, você está pronto para começar a entender ou mesmo criar um projeto empresarial Web comum de médio porte. Entretanto, este modelo muitas vezes pode ser estendido com mais pedaços de software, como Web Services, Windows Services e mesmo, alguma camada de aplicação RIA, como Silverlight ou Flex.

Antes de encerrar este artigo, queremos deixar claro que quase sempre compensa fazer este tipo de solução, com componentes separados em camadas. O que se vê por aí é que o projeto começa pequeno, cresce desordenadamente e fica impossível de se trabalhar com o tempo. Logo, o tempo inicial para montagem da solução compensa o esforço de refactoring futuro.

Para baixar esta solução de exemplo, clique aqui para obter a solução em formato zip, utilizando Visual Studio 2008 Team System e compilado em .NET Framework 3.5 SP1. No projeto de testes, referenciamos a DLL NUnit.Framework.

Dúvidas, Sugestões, Reclamações ou Dicas? Comente!

Grande abraço!
Mário Meyrelles (http://twitter.com/mariomeyrelles)
Equipe Accendis

, , ,
Adicionar aos Favoritos BlogBlogs Adicionar esta notícia no Linkk

Introdução

Criação e codificação de formulários é uma das principais tarefas no desenvolvimento de aplicativos ASP.NET. Normalmente as informações digitadas precisam ser validadas para que os dados processados ou armazenados na base sejam obrigatoriamente válidos.

Nos tempos do ASP clássico, boa parte das tarefas da validação eram realizadas através de JavaScript. Apenas os profissionais muito caprichosos tinham a cautela de realizar a validação TAMBÉM no servidor. Esse procedimento se faz necessário pela possibilidade do usuário desabilitar o uso de JavaScript em seu navegador e com isso não estar sujeito a validação.

No ASP.NET existem controles específicos para validação que fazem parte do Microsoft .NET Framework. Esses controles realizam a validação nos dois lados da aplicação: cliente e servidor. Nesse post falarei dos mais utilizados, porém se você precisar de mais alguma informação que não encontrou aqui acesse a página que explica os controles detalhadamente no MSDN: http://msdn.microsoft.com/pt-br/library/debza5t0.aspx

RequiredFieldValidator

O tipo de validação mais comum é fazer com que um determinado campo tenha conteúdo obrigatório. Para esse tipo de validação deve-se utilizar o controle RequiredFieldValidator.

Assim como todos os controles que vamos exemplificar nesse post, o RequiredFieldValidator se encontra no grupo Validation da Toolbox.

Para utilizar esse controle você deverá realizar as seguintes configurações:

Nome:
<asp:RequiredFieldValidator ID="rfvNome" runat="server"
     ControlToValidate="txtNome" ValidationGroup="Cadastro"
     ErrorMessage="O campo nome é obrigatório">
</asp:RequiredFieldValidator>
<br>
<asp:TextBox ID="txtNome" runat="server"
     ValidationGroup="Cadastro">
</asp:TextBox>
<br>
<asp:Button ID="btnSalvar" runat="server"
     Text="Salvar" ValidationGroup="Cadastro">
</asp:Button>

Como resultado desse exemplo você obterá uma validação de campo obrigatório atuando no campo Nome. Se o usuário apertar o botão Salvar sem ter informado algum valor no campo Nome a mensagem “O campo nome é obrigatório” será exibida.

RegularExpressionValidator

Digamos agora que nossa necessidade é verificar se a informação inserida em um campo atende a um critério pré-estabelecido.

Para solucionar esse problema utilizaremos o controle RegularExpressionValidator. Através de uma expressão regular que será configurada no controle faremos a validação da informação.

Em nosso exemplo vamos verificar se um endereço de e-mail é válido. Nesse exemplo para simplificar o código escrevi apenas o bloco do RegularExpressionValidator deixando de lado o TextBox e o Button que são necessários para o teste completo.

<asp:RegularExpressionValidator ID="revEmail" runat="server"
     ControlToValidate="txtEmail" ValidationGroup="Cadastro"
     ErrorMessage="Endereço de e-mail inválido."
     ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
</asp:RegularExpressionValidator>

O resultado desse exemplo é a validação do endereço de e-mail atuando no campo E-mail. Se a informação digitada não for válida após a validação do formulário será exibida a mensagem “Endereço de e-mail inválido”.

ValidationSummary

Em formulários muito extensos é muito comum que o desenvolvedor necessite exibir em um único lugar todas as mensagens de erro de validação. Para essa finalidade existe um controle chamado ValidationSummary.

A sintaxe para uso desse controle é bastante simples e prática:

<asp:ValidationSummary ID="vlsCadastro" runat="server"
     ValidationGroup="Cadastro" />

Com o uso desse controle, após a validação serão exibidos no local desejado todas as mensagens de erro de validação.

Esses são os três principais controles utilizados na validação de formulários ASP.NET. Como sempre, espero que esse post seja de grande ajuda para a comunidade de desenvolvedores .NET.

Um grande abraço a todos!

,
Adicionar aos Favoritos BlogBlogs Adicionar esta notícia no Linkk

Introdução

Durante as tarefas de desenvolvimento de aplicativos ASP.NET é muito comum a necessidade de recuperar variáveis relacionadas ao servidor e também aos caminhos físicos e relativos da página atual.

Devido a essa constante necessidade estou escrevendo esse post que explica as principais variáveis de servidor do objeto Request.

APPL_PHYSICAL_PATH

Utilizada para recuperar o caminho físico onde está configurado o servidor de aplicação.
Por exemplo: C:\Inetup\wwwroot\Sites

AUTH_USER

Recupera o nome do usuário autenticado.
Por exemplo: ACCENDIS\Aubry Maciel

PATH_INFO

Utilizado para recupear o endereço relativo desde a pasta inicial do servidor de aplicação até o nome da página atual.
Por exemplo: /sites/treinamentos/promocoes.aspx

PATH_TRANSLATED

Retorna o caminho físico completo do arquivo correspondente a página atual.
Por exemplo: C:\Inetpub\wwwroot\sites\treinamentos\promocoes.aspx

Exemplo de utilização

Para acessar os valores contidos nessas variáveis é muito simples. As variáveis estão armazenadas dentro do objeto Request dentro de uma lista chamada ServerVariables.

    Request.ServerVariables["PATH_INFO"]

Não citei e exemplifiquei todas as variáveis existentes pois a lista é um pouco extensa e nem todas tem a mesma relevância. Para complementar o post e permitir que você possa se aprofundar mais segue uma lista com todas a variáveis.

ALL_HTTP ALL_RAW APPL_MD_PATH
APPL_PHYSICAL_PATH AUTH_TYPE AUTH_USER
AUTH_PASSWORD LOGON_USER REMOTE_USER
CERT_COOKIE CERT_FLAGS CERT_ISSUER
CERT_KEYSIZE CERT_SECRETKEYSIZE CERT_SERIALNUMBER
CERT_SERVER_ISSUER CERT_SERVER_SUBJECT CERT_SUBJECT
CONTENT_LENGTH CONTENT_TYPE GATEWAY_INTERFACE
HTTPS HTTPS_KEYSIZE HTTPS_SECRETKEYSIZE
HTTPS_SERVER_ISSUER HTTPS_SERVER_SUBJECT INSTANCE_ID
INSTANCE_META_PATH LOCAL_ADDR PATH_INFO
PATH_TRANSLATED QUERY_STRING REMOTE_ADDR
REMOTE_HOST REMOTE_PORT REQUEST_METHOD
SCRIPT_NAME SERVER_NAME SERVER_PORT
SERVER_PORT_SECURE SERVER_PROTOCOL SERVER_SOFTWARE
URL HTTP_CONNECTION HTTP_ACCEPT
HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_HOST
HTTP_USER_AGENT

Espero que esse post ajude você em seus estudos!

Até a próxima. Um abraço a todos!

,
Adicionar aos Favoritos BlogBlogs Adicionar esta notícia no Linkk

Hoje farei o primeiro POST técnico de nosso blog. Falarei sobre os PageMethods, um recurso bastante útil do AJAX no ASP.NET.

É muito comum a necessidade de realizar algum tipo de operação no lado servidor da aplicação sem renderizar novamente grandes blocos de código HTML. As vezes a idéia é atualizar apenas um pequeno valor que é calculado no servidor e exibí-lo em uma label, ou então atualizar um ícone de acordo com o status de uma operação.

Os PageMethods são chamadas de métodos no servidor utilizando Javascript. Para utilizá-los algumas pequenas configurações e implementações são necessárias. Para ilustrar os procedimentos vou utilizar um exemplo bem simples. Nosso exemplo consiste na necessidade de realizar a soma de dois números. Apesar de ser uma operação bastante simples e que poderia ser realizada apenas através de Javascript, vamos imaginar que essa soma só pudesse ser realizada no lado servidor da aplicação.

1 – Formulário

Nosso formulário contém apenas duas caixas de texto, um botão e uma span (controle onde será exibido o resultado do cálculo).

<form id="form1" runat="server">
    <asp:ScriptManager runat="server" EnablePageMethods="true">
    </asp:ScriptManager>
    <div>
        <p>
            Primeiro número:<br />
            <input type="text" id="numero1" />
        </p>
        <p>
            Segundo número:<br />
            <input type="text" id="numero2" />
        </p>
        <p>
            <input type="button" value="Somar"
                      onclick="javascript: somar();" />
        </p>
        <p>
            Resultado:<br />
            <span id="resultado"></span>
        </p>
    </div>
</form>

É importante atentar para a necessidade de existir um ScriptManager na página e que o mesmo tenha habilitado o uso de PageMethods.

<asp:ScriptManager runat="server" EnablePageMethods="true">
</asp:ScriptManager>

2 – Operação no codebehind

Agora criaremos no codebehind o método responsável por realizar a soma dos números. Para que tudo funcione corretamente não se pode esquecer o atributo WebMethod que deve ser colocado logo acima do método. Outro detalhe importante é que o método deve ser estático para que possa ser acessado através de Javascript.

1
2
3
4
5
6
7
8
9
10
11
/// <summary>
/// Realiza a soma de dois números.
/// </summary>
/// <param name="numero1">Primeiro número.</param>
/// <param name="numero2">Segundo número.</param>
/// <returns>Resultado da soma.</returns>
[WebMethod]
public static string Somar(int numero1, int numero2)
{
    return (numero1 + numero2).ToString();
}

3 – Métodos no cliente

Para controlar os eventos e atualizar o resultado da operação na página é necessário que sejam implementados alguns métodos em javascript. Em nosso exemplo teremos 3 métodos:

  • somar: método que é chamado quando o botão Somar é clicado. Esse método é responsável por recuperar os valores do formulário e realizar a chamada da operação no servidor.
  • OnSucceed: é chamado através de callback automaticamente quando a operação no servidor for realizada com sucesso.
  • OnFailed: é chamado através de callback automaticamente quando ocorrer falha na operação executada no servidor.

Abaixo segue o código das três funções em javascript responsáveis pelo controle da tela:

// Realiza a soma dos dois números informados na tela.
function somar() {
    txtNumero1 = document.getElementById('numero1');
    txtNumero2 = document.getElementById('numero2');        
    PageMethods.Somar(txtNumero1.value, txtNumero2.value,
                                OnSucceeded, OnFailed);
}
 
// Executado através de callback em caso de sucesso.
function OnSucceeded(result, userContext, methodName) {
    resultado = document.getElementById('resultado');
    resultado.innerHTML = result;
}
 
// Executado através de callback em caso de falha.
function OnFailed(error, userContext, methodName) {
    resultado = document.getElementById('resultado');
    resultado.innerHTML = 'Erro ao executar soma';
}

O resultado desse exemplo é simples. Sempre que o botão Somar for pressionado, o método somar recupera o valor dos dois números informados no formulário, realiza a requisição ao método Somar no servidor e através do callback atualiza o conteúdo da SPAN resultado.

Espero que esse post possa auxiliar e agregar conhecimentos aqueles que acompanham nosso blog.

Agradeço a todos pelo apoio e visitas.

Um grande abraço. Até a próxima.

,
Adicionar aos Favoritos BlogBlogs Adicionar esta notícia no Linkk