domingo, 20 de setembro de 2009

Criando e Consumindo Serviços no Silverlight - Parte 1


Intrudução

Desde que o Silverlight 2 foi lançado eu comecei a estudar essa tecnologia. O Silverlight permite criar aplicações ricas na internet, ou seja, aplicações que se aproximam muito de uma desktop. Antes disso eu fazia aplicações com ASPX, mas só ASPX não era suficiente, tinha que integrar com Ajax/JScript para poder criar uma aplicação que funcionasse de maneira intuitiva para o usuário.

Foi ai que surgiu a ideia de usar o Silverlight 2, mas para uma aplicação funcionar tem que ter o famoso CRUD(Create, Retrieve, Update e Delete), em outras palavras o usuário tem que inserir, buscar, alterar e deletar dados e esses dados tem que ser persistentes.
Minha maior dificuldade no inicio foi justamente criar um serviço para fazer conexão com o banco e consumi-lo no Silverlight para criar meu CRUD.

Nesse tutorial vou ensinar a criar um web service em um projeto web comum e configurá-lo para que você use ele na sua aplicação do Silverlight 2 ou 3.

Esse artigo é para quem já tem um servidor e não sabe criar um web service para o Silverlight ou está tendo problemas para fazer funcionar.

Criando o WebSite

Vou criar um projeto do tipo website em uma solução separada do projeto do Silverlight, talvez você já tenha um projeto website pronto e você queira colocar o serviço nele, fica ao seu critério.

Para criar o projeto WebSite pelo menu:
File->New WebSite-> ASP.Net WebSite

Figura 1 - Criando o Web Site
Figura1 - Criando o Web Site

Damos um nome para o projeto e escolhemos também a linguagem como mostra a figura 1, eu irei disponibilizar o código para C# e VB.Net.

Criando o Web Service no WebSite

Para criar o serviço pelo menu:
WebSite->Add New Item->Silverlight-Enabled WCF Service

Figura 2 - Criando o Serviço no projeto Web Site
Figura2 - Criando o Serviço no projeto Web Site

Esse tipo de serviço é muito parecido com o tradicional ASMX que talvez você já esteja habituado. Tudo que você faz com o ASMX é possível fazer com o WCF.

O serviço fica divido em dois arquivos, um com a extensão '.svc' que fica na raiz e a classe(.cs/.vb) que fica na pasta App_Code, como mostra na figura 3, logo abaixo.

Figura 3 - Solution Explorer
Figura 3 - Solution Explorer

Apos criarmos o serviço ele vem com um método de exemplo que é o DoWork. Todo método que você deseja utilizar na sua aplicação deve ter o atributo 'OperationContract', caso contrario ele não será visto por sua aplicação.
Bem vamos criar um novo método para testar nosso serviço.

CSharp

[OperationContract]
public string DizOi()
{
 return "Hello World";
}

VB.Net

<OperationContract()> _
Public Function DizOi() As String
 Return "Hello World"
End Function

Ainda Falta Alguma Coisa...

Esse é o ponto chave, o pulo do gato, a risada da hiena, o rugido do leão... hehehe
Se você rodar no localhost irá funcionar perfeitamente mas talvez no seu servidor não rode!
Um jeito de você testar rapidamente se o seu serviço está ok é acessando via browser, exemplo: "www.meusite.com/meuapp/servico.svc".
Você pode se deperar ou já está se deparando com um erro semelhante a esse:

Server Error in '/MeuWebApp' Application.

This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
Parameter name: item

Implementando a Factory

Bem, falta implementar a factory que é bem simples (quando você já tem um código pronto hehe).
Adicione uma classe no seu projeto web como ilustra a figura abaixo:

Figura 4 - Adicionando uma Classe no Projeto
Figura 4 - Adicionando uma Classe no Projeto

Nessa classe você colocará o código abaixo:

CSharp

using System.ServiceModel.Activation;
using System.ServiceModel;
using System;

public class MeuServicoFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        // Coloque o endereço do seu servico na string abaixo
        Uri webServiceAddress = new Uri("http://www.SEUSITE.com/MeuServico.svc");
        ServiceHost webServiceHost = new ServiceHost(serviceType, webServiceAddress);
        return webServiceHost;
    }
}

VB.Net

Imports Microsoft.VisualBasic
Imports System.ServiceModel.Activation
Imports System.ServiceModel


Public Class MeuServicoFactory
    Inherits ServiceHostFactory

    Protected Overloads Overrides Function CreateServiceHost(ByVal serviceType As Type, ByVal baseAddresses As Uri()) As ServiceHost
        ' Coloque o endereço do seu serviço na string abaixo
        Dim webServiceAddress As New Uri("http://www.SEUSITE.com/MeuServico.svc")
        Dim webServiceHost As New ServiceHost(serviceType, webServiceAddress)
        Return webServiceHost
    End Function
End Class

Coloque o endereço do seu serviço(.svc) no construtor da Uri como ilustrado no código acima.

Agora falta referenciar a factory no serviço, para isso abra o arquivo '.svc', você encontrará definições do seu serviço.
Depois da especificação do 'Service="MeuServico"' coloque uma especificação para o factory colocando o nome da sua classe factory 'Factory="MeuServicoFactory"'.

Seu '.svc' ficará assim:

<%@ ServiceHost Language="C#" Debug="true" Service="MeuServico"Factory="MeuServicoFactory" CodeBehind="~/App_Code/MeuServico.cs" %>

Testando o Serviço no Navegador

Com a factory criada e marcada no '.svc' vamos testar, copie o seu web site para o servidor e acesse ele no navegador. Se o seu web service estiver "saudavel" aparecerá no navegador dois exemplos de como usar ele na aplicação, como a imagem abaixo.

Figura 5 - Serviço Funcionando no Browser
Figura 5 - Serviço Funcionando no Browser

No Próxima Parte

Na segunda parte desse tutorial iriei ensinar como consumir o serviço no Silverlight.
Espero ter ajudado já nessa primeira parte a fazer o serviço funcionar corretamente no servidor, dessa maneira ele está preparado para ser referenciado na aplicação Silverlight.

Até breve,
Tiago Esmeraldino

quinta-feira, 17 de setembro de 2009

DICA: Ferramenta Para Converter Código VB.Net/C#

Acho que nem todos sabem mas existe ferramentas que convertem código C# para VB.Net e vice-versa.

A melhor que eu encontrei é essa online gratuita:
http://www.developerfusion.com/tools/convert/csharp-to-vb/

Ela é beseada na SharpDevelop que é uma IDE gratuita para .Net, uma solução para quem não gosta do Visual Studio.

Talvez você não quer converter seus projetos, mas as vezes procuramos códigos na Web e estão em C# ou em VB.Net e a solução mais rápida para converter o código é com essa ferramenta.

Fica a dica.

Até a próxima,
Tiago Esmeraldino

quinta-feira, 10 de setembro de 2009

Prefiro C# do que VB.Net - Parte 3


Introdução

Nessa ultima parte irei abordar uns dos principais atrativos da sintaxe do C# e vou comentar um pouquinho sobre o futuro muito próximo das duas linguagens.

Quebrando _
    Linha

A sintaxe do VB.Net trabalha com quebras de linha para simbolizar o fim de uma instrução, diferente de outras linguagens que utilizam o ponto e virgula. Isso significa que você não pode quebrar uma linha sem o underline que acaba deixando o código um pouco estranho.

Isso não seria tão ruim se boa parte das palavras chaves do VB.Net não deixasse o código grande, e isso gera uma necessidade ainda maior de quebrar as linhas.

O recurso mais aplaudido do VB.Net 10 sem duvida é a possibilidade de quebrar o código em alguns pontos sem o underline, e esses pontos são uteis o que é muito bom. Mas enquanto não chega 2010 e não atualizamos nossas aplicações para o framework 4.0 isso continua sendo um atrativo para eu programar em C#.

Como eu disse, as palavras chaves do VB.Net é tudo grande, até para você dizer que a variável é nula é preciso de um 'Nothing' no lugar do'null'. Isso
porque a sintaxe do VB.Net é mais próxima do inglês o que deve ajudar os iniciantes, se eu abrir um 'If' preciso do 'End If' e na maioria das vezes é 
tudo assim(function, sub, class e etc).

Isso deixa o código um pouco poluído, alem do mais apesar de ser intuitivo ninguém precisa colocar o 'End <comando>' porque a IDE ajuda de todos os jeitos e na maioria das vezes basta um enter para ela escrever o resto para você.  Por outro lado você consegue saber rapidamente onde abre e onde fecha cada comando.

Um exemplo de um método simples:

Public Function Soma(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
 Dim ret As Integer = num1 + num2
 Return ret
End Function

No C#:

public int Soma(int num1, int num2) 
{
 int ret = num1 + num2;
 return ret;
}

Nesse pequeno exemplo mostra que no C# não precisa das palavras chaves na assinatura do método: function, as, byval. E na declaração não precisa do 'Dim' e 'As'.
Não vou listar mais comparações porque tem esse site cheio de comparações.

Quando é um método com vários parâmetros é bom pensar se esses parâmetros não deveriam estar em  uma classe, mas quando não tem como criar uma classe o VB.Net se sai muito ruim. A solução é comprar um monitor widescreen ou utilizar as quebras com underline, a segunda opção é mais viável hehehe.

O Futuro Não Muito Distante

Há funcionalidades legais que só tem no VB.Net e tem outras que só tem no C#. Na próxima versão o C# 4.0 virá com parâmetros nomeados e opcionais, late binding e o VB.Net 10 alem da quebra de linha terá auto propertys. Funcionalidades interessantes que hoje é um atrativo de cada linguagem mas no futuro será tudo(quase) igual, só mudando a sintaxe(que é o que eu gosto no C#).

Até Mais,
Tiago Esmeraldino

quarta-feira, 2 de setembro de 2009

Prefiro C# do que VB.Net - Parte 2


Introdução

Continuando as razões de eu preferir a sintaxe do C#. Na primeira parte abordei dois pontos da linguagem que apesar de ser maneiras de auxiliar quem veio do VB6 poderia confundir na parte de orientação a objetos. Mas elas eram apenas duas exceções da linguagem.

Vamos continuar então.

Membros Públicos dos Módulos

Você sabe o que é um módulo?

Um módulo é uma classe onde tudo nela é shared(static em C#) por padrão.

Então o modulo seria equivalente a isso no C#:

public static class MinhaClasse 
{
}

Então qual o problema do módulo ou melhor dizendo classe shared no VB.Net?

Seus métodos, atributos públicos são vistos em todos os lugares sem
precisar mencionar o modulo(classe).

Por exemplo, criei um "Module1" com uma property(Id), por ser shared eu nem devo instanciar um objeto para acessar a variável, basta colocar o nome da classe ou modulo assim:

 Module1.Id = 1

Mas no VB.Net você consegue setar a property sem nem ao menos colocar o nome da classe na frente, ou seja, você está numa classe totalmente diferente e pode utilizar os membros de um modulo como se você estivesse dentro do modulo:

Id = 1  

Você pode estar se perguntando, o que tem de errado nisso?
Vou dar um exemplo: Um programador cria um “MdlGlobal”, modulo com propósito de conter variáveis e métodos globais, e coloca lá variáveis e métodos que ele quer que seja acessados por toda aplicação, mas para não confundir com membros de outras classes acabaram colocando prefixos nos nomes para dizer que é Global, exemplo: GlobalUsuarioID, GlobalVariavelX (e etc)

Isso acaba deixando tudo mais confuso, se fosse obrigatório o nome do modulo não precisaria de prefixos: MdlGlobal.UsuarioID, MdGlobal.VariavelX

Não ficou mais fácil? Alem de deixar os nomes menos carregados você sabe rapidamente da onde está vindo o método ou atributo.

Da para deixar de usar módulos criando uma classe e colocando os membros como shared, é uma alternativa.
É fato que quando usamos shared deixamos o código menos orientado a objetos, mas nem mencionar a classe daí já é demais.

Método/Método()

No VB.Net na passagem de parâmetros de métodos é obrigatório colocar os parênteses a não ser quando não há parâmetros.

Dim letras As Object = "a b c d e f g"
Dim array As String() = letras.ToString.Split

O exemplo acima talvez não esteja confuso, porque os métodos ToString e Split tem nomes intuitivos, da para entender que está executando dois métodos. Mas quando o programador coloca um nome nada a ver para um método? Um nome que deveria ser de um atributo? Bem, no Visual Studio basta passar o mouse em cima para descobrir, mas não deixa de ser confuso as vezes.

Mas isso pode ficar mais confuso combinado com as genérics que é o próximo tópico.

Generics com Parênteses

As generics são muito utilizadas, com ela tem um ganho muito bom em performance e em segurança.

Vamos declarar então uma lista de usuários.

Dim usuarios As List(Of Usuario)

Eu declarei usuarios como List(Of T), o T é a genéric que vai ser o meu tipo Usuario.
Ok, eu não instanciei ainda a minha lista.

usuarios = New List(Of Usuario)

Pronto, instanciei uma lista, nesse momento um método é executado, que é o construtor da classe. Por não ser obrigatório o uso de parênteses pode dar a impressão de que '(Of T)' que é a generic é o construtor ou que o construtor nem existe.

Dim usuarios As New List(Of Usuario)(100)

Veja agora, você não acha que isso é bizarro? Estou passando um parâmetro para o construtor da lista e ficou com quatro parênteses na minha declaração.
No C# ficaria assim:

List<Usuario> usuarios = new List<Usuario>(100);

No C# as generics ficaram menos confusas ou ao menos não tem como confundir com o construtor da classe.

Índices com Parênteses

Os indexadores no VB.Net também usa parênteses para acessar os índices de arrays e coleções em geral.

Exemplo:

x = numeros(1)

Estou atribuindo o valor da posição 1 para a variável ‘x’.
Nenhuma confusão até agora, pois o meu array está com um nome que sugere que é um array ou uma lista e ainda está em camelCasing que é uma boa pratica.

Digamos então que o programador não segue boas práticas:

x = SomaNumeros(1)

O que é SomaNumeros? O programador colocou um nome ambíguo, que para ele deve significar muita coisa e fazer todo o sentido do mundo.
Será que é uma lista ou array com resultados de uma soma ou é um método? Descobriremos somente se olharmos a definição, e isso não é bom.

A sintaxe do C# utiliza colchetes para indexar, então não tem erro:

x = SomaNumeros[1];

Declarando Arrays

Quantas posições estou alocando com a declaração abaixo?

Dim numeros(10) As Integer

A resposta é onze!
No VB.Net ele aloca de zero até o número especificado, que no caso é dez.

No C# alocaria de zero a nove dando sentido ao número explicito da declaração. 

Isso induz o programador deixar de usar o endereço zero desperdiçando memória.

Mas você quer ver como isso pode ficar estranho?

Dim numeros(0) As Integer

Declarei acima um array de apenas uma posição com o número zero.

Chegando ao Fim da Parte 2

Eu abordei nessa segunda parte pontos da sintaxe do VB.Net.
Quando escrevemos um código limpo, com bons nomes nas variáveis e bem documentado não há confusão alguma independente da linguagem.
Então é bom nos disciplinar para fazer um código que facilite a manutenção.

Há mais ponto que me incomoda na linguagem, mas ficará para a terceira parte.

Até Mais,
Tiago Esmeraldino