segunda-feira, 14 de maio de 2012

Como criar um serviço no Windows para envio de e-mails utilizando .NET

O que é um serviço do Windows ?

Um serviço é um tipo de aplicativo que é executado em segundo plano pelo sistema operacional sem a necessidade de uma interação com o usuário.

Dentro do Visual Studio é possível criar um serviço utilizando-se o template de projeto windows indicado como "Windows Service".

O arquivo executável que é gerado a partir da compilação de um projeto do tipo "Windows Service" não é igual ao arquivo gerado de uma aplicação Windows, portanto, não basta apenas clicar sobre ele para executar, ele precisa ser instalado como um serviço.

Devemos então utilizar o Visual Studio para incluir um instalador para o nosso serviço.
Ao final, precisamos instalar o serviço utilizando o programa "InstallUtil.exe", que é um utilitário .NET para instalar serviços do Windows. Ele deverá ser executado na janela do prompt do Visual Studio, e deverá ser informado o path completo do assembly que será instalado. Foram criados 2 exemplos práticos de como criar um serviço no windows



Veja na vídeo-aula abaixo uma demonstração de como criar um serviço simples do windows:




Veja na vídeo-aula abaixo uma demonstração de como criar um serviço para envio de e-mails:


sábado, 21 de abril de 2012

Como criar uma aplicação para enviar e-mail utilizando .NET

Atualmente diversos aplicativos necessitam de um serviço para envio de e-mail.
Podemos criar uma aplicação de exemplo utilizando as classes abaixo:

Classe: MailAddress
Namespace: System.Net.Mail.MailAddress

Ela representa um endereço de e-mail qualquer, seja do remetente ou destinatário. Esta classe será utilizada pela classe "MailMessage" para armazenar os endereços, de origem e destino, da mensagem.

Além do endereço de e-mail , esta classe também pode armazenar um "nome" para  ser exibido ao lado do endereço de e-mail quando a mesnagem for visualizada. O nome desta propriedade é "DisplayName"

Classe: MailMessage
Namespace: System.Net.Mail.MailMessage
Repesenta uma mensagem de e-mail que pode ser enviada através da classe "SmtpClient"

O remetente, destinatário, assunto e corpo de uma mensagem de e-mail podem ser especificados como parâmetros quando um objeto MailMessage é inicializado. Estes parâmetros também podem ser definidos ou acessados ​​usando as propriedades no objeto MailMessage.

Classe: SmtpClient
Namespace: System.Net.Mail.SmtpClient

Esta classe permite que aplicações possam enviar e-mail utilizando o protocolo SMTP.


Para enviar uma mensagem de e-mail utilizando a classe SmtpClient você deve especificar as seguintes propriedades:

* Host
O servidor host de SMTP que será utilizado para enviar o e-mail, no exemplo irei utilizar o gmail.

* Credentials
 Credenciais para
autenticação, se exigido pelo servidor SMTP, no meu exemplo será necessário.

* EnableSsl
Informar se o servidor de SMTP utiliza SSL para encriptar a conexão.


* UseDefaultCredentials
No meu caso irei passar "false", pois vou passar as minhas credenciais através da propriedade "Credentials" descrita acima.

Veja abaixo uma vídeo-aula contendo um exemplo prático:



Veja abaixo um código de exemplo. Para este código funcionar é preciso adicionar 2 namespaces:

using System.Net;
using System.Net.Mail;

private void enviarEmail()
{
     MailAddress remetente = new MailAddress(emailorigem@gmail.com, "Nome da Origem"); 
     MailAddress destino     = new MailAddress(emaildestino@gmail.com, "Nome do Destino");

     MailMessage msg = new MailMessage(remetente, destino);
     msg.Subject          = "Assunto da mensagem";
     msg.Body             = "Corpo da mensagem";

     SmtpClient smtp                   = new SmtpClient();
     smtp.Host                              = "smtp.gmail.com";
     smtp.Port                              = "587";
     smtp.EnableSsl                     = true;
     smtp.UseDefaultCredentials = false;

     smtp.Credentials = new NetworkCredential(remetente.Address, "Senha do emailorigem");
     smtp.Send(msg);
}

Trabalhando com imagem em banco de dados utilizando .NET

Em .NET é possível salvar e recuperar imagens em banco de dados de froma simples, utilizando algumas classes do framework. Seguem abaixo as classes necessárias para criarmos um exemplo:

Classe: Image
Namespace: System.Drawing.Bitmap  
É uma "classe abstrata" que fornece funcionalidades para as classes "Bitmap" e "Metafile"

Classe: Bitmap
Namespace: System.Drawing.Bitmap 
É uma classe utilizada para trabalhar com imagens, ela herda da classe abstrata "Image"

Um bitmap é um formato padrão utilizado pelo windows para "armazenar imagem". Geralmente eles não são compactados, portanto não são indicados para transferência através da internet, Ele consiste, basicamente, em dados de pixel de uma imagem. 

Podemos salvar um bitmap em arquivo em alguns formatos padrões como: BMP, GIF, EXIF, JPG, PNG e TIFF. Para obter mais informações sobre os formatos suportados, consulte Tipos de Bitmaps.

Classe: MemoryStream
Namespace: System.IO.MemoryStream
Classe utilizada para se trabalhar com "stream" em memória

Neste exemplo ela será utilizada para gerar um array de bytes, byte[], que será gravado no nosso banco de dados. O tipo do campo na tabela deverá ser "varbinary[MAX]"
 

OBSERVAÇÃO: Em algumas situações os analistas e desenvolvedores não gravam a imagem no banco de dados e optam por gravar os arquivos físicos das imagens no disco rígido, gravando no banco de dados apenas o "path" da imagem. Se você gravar somente o caminho da imagem em uma tabela do banco de dados, economizará, principalmente, espaço no seu banco de dados


Veja na video-aula abaixo como INSERIR uma imagem em banco de dados:




 

Veja na video-aula abaixo como RECUPERAR uma imagem gravada em um banco de dados e exibí-la em uma aplicação .NET:

terça-feira, 27 de março de 2012

Serialização de Objetos em .NET

Muitas aplicações necessitam armazenar ou transferir objetos.

Quando criamos um objeto em um aplicativo, geralmente não nos preocupamos em como os dados serão armazenados na memória. No entanto, se você desejar armazenar o conteúdo de um objeto em um arquivo, enviar um objeto para outro processo, ou transmitir um objeto pela rede, você precisará convertê-lo para um formato diferente. Esta conversão é chamada de serialização.

Serialização é o processo de conversão de um objeto para uma sequência linear de bytes que podem ser armazenados em arquivos e transferidos. Podemos também entender como sendo um armazenamento do "estado" de um objeto.

Descerialização é o processo de converter uma sequência previamente serializada de bytes em um objeto, ou seja, é "recriar" o objeto que foi serializado com o mesmo estado (propriedades)

Se você desejar armazenar um objeto em um arquivo para posterior recuperação, você irá armazenar a "saída de uma serialização". A próxima vez que você quiser ler este objeto, deverá chamar os métodos de descerialização, e seu objeto será "recriado" exatamente como estava no momento em que foi serializado. 

Da mesma forma, se você quiser enviar um objeto para um aplicativo em execução em outro computador, você pode estabelecer uma conexão de rede, serializar o objeto, e depois descerializar o objeto no aplicativo remoto.

Na prática a serialização pode ser implementada com muito pouco código. O exemplo abaixo, que requer os namespaces "System.IO" e "System.Runtime.Serialization.Formatters.Binary"demonstra isto.

Os passos para serializar um objecto são:
  • Criar um objeto "stream" para receber o resultado da serialização.
  • Criar um objeto BinaryFormatter (localizado no namespace System.Runtime.Serialization.Formatters.Binary).
  • Chamar o método "Serialize" de "BinaryFormatter" para serializar o objeto e armazenar a saída no objeto "streram" criado no  passo 1.

Veja abaixo um exemplo de código escrito em c#:


(1)  string data = "Isto será armazenado em arquivo";
(2)  FileStream fs = new FileStream("StringSerializada.data", FileMode.Create);
(3)  BinaryFormatter bf = new BinaryFormatter();
(4)  bf.Serialize(fs, data);
(5)  fs.Close();

Veja o passo-a-passo do que aconteçeu:

(1) Foi criado um objeto que será serializado, neste caso uma simples variável do tipo "string", mas poderia ser qualquer "object". É importante saber o tipo de objeto que está sendo serializado para poder fazer o "cast" de forma correta no momento de descerializar.

(2) Foi criado um arquivo em disco, com o nome "StringSerializada.data", para armazenar a informação serializada.

(3) Foi criado um objeto BinaryFormatter para realizar a serialização

(4) Foi utilizado o método "Serialize" do objeto "BinaryFormatter" para serializar a informação contida na variável "data" em um arquivo.

(5) O arquivo serializado foi fechado

Se você abrir este arquivo com o "notepad", poderá observar que o mecanismo de serialização do .NET armazena a string como texto ASCII e, em seguida, acrescenta mais alguns bytes binários antes e depois do texto para "descrever" os dados para o "descerializador".

Se tentarmos serializar um objeto qualquer ao invés de uma variável do tipo string, a classe deste objeto deverá possuir um atributo de classe conhecido como "Serializable". Conforme no exemplo abaixo:

[Serializable]
public class Aluno
{

}

Não percam os exemplos práticos, de como serializar e descerializar um objeto, na vídeo-aula abaixo:

Serializar e Descerializar Dados:



Serializar e Descerializar Objetos:


domingo, 18 de março de 2012

Strings são Imutáveis - String X StringBuilder

Neste post irei demonstrar algumas maneiras de como trabalhar com "texto" na linguagem de programação c#.  Ao final está o link para a video-aula

As classes mais utilizadas, sem dúvida, são "String" e "StringBuilder". Cada uma delas apresenta particularidades com relação a criação de objetos na memória, principalmente no relacionamento com as variáveis de referência destes objetos.

Como nós já sabemos, strings são IMUTÁVEIS. Isto significa dizer que, após feita uma atribuição de valor para uma variável do tipo "string" nunca mais poderemos alterar aquele valor. Mas então o que aconteçe quando, constantemente, nos deparamos com um código como o abaixo ?

string teste = "abc";
teste = teste + "def";

Neste exemplo simples, a linha1 cria um objeto string na memória, com o valor "abc", e faz a variável de referência "teste" apontar para o endereço de memória onde o objeto foi criado. Vamos supor que tenha sido criado no endereço de memória #001.

Na segunda linha alteramos o valor da string criada na linha1. É exatamente neste ponto que se concentra toda a discussão e confusão sobre o tema de imutabilidade. Após a linha2 a variável "teste" ficará com o valor "abcdef", porém, este novo valor estará em uma nova área de memória que foi alocada automaticamente quando você concatenou o valor antigo da string "abc" com o valor "def".

3 coisas muito importantes aconteceram neste ponto:
1 - Um novo endereço de memória foi criado, por exemplo #030, e atribuido a ele o valor "abcdef";
2 - A variável de referência "teste" passou a apontar para este novo endereço de memória;
3 - Portanto, o endereço de memória #001 fica sem ter nenhuma referência apontando para ele, e ninguém mais irá conseguir alcancá-lo. Ele se torna elegível para ser retirado da memória através de um processo automático do framework conhecido como "Garbage Collector"

Agora vamos supor o segiunte cenário:
string s1 = "abc";
string s2 = s1;
s2 = "123";

Este cenário é parecido com o anterior, porém, neste caso não ficamos com um endereço de memória inalcanssável. Vejamos o passo-a-passo resumido do que aconteçeu:

1 - É alocado um novo endereço de memória, por exemplo #050, para a variavel de referência s1;
2 - É declarada uma nova variavel s2, que aponta para o mesmo endereço de memória de s1;
3 - s2 deixa de apontar para o endereço de memória #050 e passa a apontar para um novo endereço de memória que foi alocado automaticamente, por exemplo #052, quando o valor "123" foi atribuido à variàvel s2.
4 - s1 continua apontando para seu endereço de memória de origem, #050, com o mesmo valor "abc"

Veja abaixo o gráfico do cenário descrito acima. Esta imagem foi retirada da revista  "easyJava, número 1, edição 1".



Sempre que você precisar fazer muitas concatenações com strings dê preferência ao objeto StringBuilder, pois ele consegue alocar um único endereço de memória e "crescer" de forma dinâmica conforme você vai "concatenando" mais strings. Veja abaixo um exemplo.

StringBuilder sb = new StringBuilder();
sb.Append("abc");
sb.Append("def");
sb.Append("ghi");

string teste = sb.ToString();

Não deixem de conferir os exemplos práticos na vídeo-aula abaixo:


quinta-feira, 23 de fevereiro de 2012

Fundamentos sobre Arquitetura de Software

Arquitetura = {Elementos, Organização, Decisão}

Arquitetura de Software pode ser entendida como estrutura ou estruturas de um sistema o qual compreende elementos de software e os relacionamentos entre eles. Ela engloba o conjunto de decisões significativas na organização de um sistema, realizando uma divisão em alto-nível de um sistema em suas sub-partes.

Construir a arquitetura de um software é muito mais do que desenvolver o software, é construir uma "visão". O arquiteto deverá identificar qual a melhor forma de abordar determinados problemas e como os elementos ao redor destes problemas se relacionam, ele poderá lhe dizer o que deverá ser feito (CAMINHO DAS PEDRAS), mas não como deverá ser feito. Dentro de um contexo de desenvolvimento de software podemos dizer que a arquitetura abrange o lado público das interfaces, os detalhes de implementação já não fazem parte das tarefas de arquitetura. Podem existir múltiplas arquiteturas dentro de um sistema

Assim como qualquer solução complexa, um software complexo também precisa ser construído sobre uma base sólida. Falhar em considerar cenários importantes  ou tratamento de problemas comuns podem levar o seu projeto ao fracasso. Mesmo com a existência de ferramentas de desenvolvimento modernas e plataformas que auxiliam na criação de um sistema, NADA SUBSTITUI O PROCESSO DE DESIGN.

Os riscos expostos por uma arquitetura ruim podem ser vistos como:
  • Software instável
  • Não atender requisitos de negócio
  • Prejudicar a distribuição do aplicativo em ambiente de produção

A arquitetura deve ser considerada como um plano estratégico nas empresas. Garantir uma boa arquitetura é garantir um bom conjunto de aplicações que podem garantir um bom conjutno de ferramenmtas para o seu negócio.

quinta-feira, 16 de fevereiro de 2012

Introdução ao ADO.NET (Modelo Conectado) - Teoria e Prática

Resumidamente, ADO.NET é o conjunto de classes utilizados para fazer acesso a banco de dados .

Quando trabalhamos com ADO.NET existem várias questões a serem consideradas. A primeira sem dúvida é o modelo de acesso aos dados que pode ser feito de duas formas: conectado e desconectado.

Ao trabalhar conectado o desenvolvedor precisa estabelecer uma conexão com a fonte de dados por onde será feita a leitura ou escrita com os dados. Isto só pode ser feito enquanto a conexão estiver aberta.

Operações tipicamente conectadas são:
1. Execução de inserção, alteração e exclusão dos dados no banco;
2. Leitura dos dados.


Segue abaixo link das vídeo-aulas que criei para auxiliar no entendimento.

Ado.Net - Modelo Conectado - PARTE I - TEORIA



Ado.Net - Modelo Conectado - PARTE II - INSERT



Ado.Net - Modelo Conectado - PARTE III - SELECT - DELETE - UPDATE