LINQ - Como criar uma aplicação web em 3 camadas (for Dummies)


Como criar uma aplicação em 3 Camadas usando LINQ to SQL ?

Mas o que seria essa tal de aplicação em camadas ?

Vamos fazer uma analogia...pense em um bolo recheado com 3 camadas como o da figura abaixo:

Em  uma arquitetura em 3 camadas você separa as responsabilidades da seguinte forma:

  1. User Interface ou Interface do usuário - UI - (um formulário windows form, wpf, uma página web, uma aplicação mobile, etc...) - que realiza a interface com o usuário;
  2. Bussiness Logic Layer - Camada de negócios - BLL - responsável por armazenar a lógica da sua aplicação
  3. Data Acess Layer - Camada de acesso a dados - DAL - responsável por realizar o acesso e a persistência aos dados fazendo a comunicação entre a BLL e UI)

Abaixo temos ume esquema simplificado desta arquitetura ao lado da imagem do bolo para comparação entre as camadas:

Vamos passar da teoria a prática criando uma aplicação que usa esta arquitetura usando o Visual Studio 2010 Beta 2. Vamos lá...

1- Abra o VS 2010 e selecione o menu File -> New Project;

2- Depois selecione a opção Other Project Types -> Visual Studio Solutions -> Blank Solution e informe o nome App3Camadas e clique em OK;

3- Clique com o botão direito sobre a solução recém criada e escolha a opção Add -> New Project;

4- Na janela Add New Project selecione Other Languages-> Visual C# -> Class Library e informe o nome BLL e clique OK;

5- Repita o procedimento do item 4 incluindo na solução o projeto do tipo Class Library chamado DAL;

6- Clique com o botão direito sobre a solução App3Camadas na janela Solution Explorer e selecione a opção Add -> New Web Site;

7- A seguir selecione Visual C# -> ASP .NET Web Site, informe o nome _webCamadaUI e clique em OK;

Ao final você deverá ver na janela Solution Explorer a solução App3Camadas contendo 3 projetos:

Obs: Eu alterei a disposição dos projetos colocando em primeiro lugar o web site , depois a BLL e em seguida a DAL para termos uma correlação entre as 3 camadas.

Como cada camada é um projeto distinto podemos até gerar um componente DLL para cada camada e referenciar em nosso projeto.(Não irei fazer isso neste artigo)

Para este exemplo devemos definir as referências entre os projetos da solução da seguinte forma:

  • O projeto do web site deverá referenciar o projeto da camada de negócios (BLL);
  • O projeto da camada de negócios (BLL) deverá referenciar o projeto da camada de acesso
    a dados (DAL) e o projeto do novo web site (UI);
  • O projeto da camada de acesso a dados deverá referenciar o projeto da camada de negócios (BLL);

Para referenciar um projeto existente selecione o projeto na janela solution Explorer e clique com o botão direito do mouse selecionando a opção Add -> Reference;

A seguir na janela Add Reference selecione a guia Projects e selecione a respectiva referência clicando no botão OK;

Começando com o web site clique com o botão direito sobre o mesmo e selecione Add Reference;

A seguir selecione cada uma das referências mostradas na guia Projects e clique em OK;

Repita este processo para o projeto BLL incluindo a referência ao projeto DAL;

Repita este processo para o projeto DAL incluindo a referência ao projeto BLL;

No projeto DAL devemos também incluir uma referência ao namespace System.Data.Linq que se encontra na guia .NET;

Terminada esta etapa nossa solução deverá possuir todas as referências definidas e estamos prontos para criar a estrutura e o código da mesma;

Antes de prosseguir com a aplicação vamos criar a fonte de dados sobre a qual iremos atuar. No nosso exemplo a nossa fonte de dados será uma tabela do banco de dados SQL Server 2008 Express.

Eu vou criar uma tabela chamada Usuarios em um banco de dados Cadastro.mdf previamente existente.(Você pode criar a tabela em qualquer banco de dados ou criar o banco de dados primeiro e depois a tabela).

Abaixo temos a figura exibindo a tabela Usuarios e sua estrutura, onde o campo id é a chave primária do tipo identidade.

Nosso objetivo será criar um web site contendo uma página que irá permitir efetuar o registro de usuários gravando o nome , email e senha de cada usuário na tabela Usuarios.

Para fazer esta inclusão eu vou usar uma stored procedure. Vamos então criar a stored procedure registraUsuario:

Agora estamos prontos para criar a aplicação que irá efetuar o registro do usuário usando o web site e o LINQ to SQL usando uma arquitetura em camadas.

Definindo a camada de acesso a dados - DAL (a base do bolo)

Vamos então começar pela camada de acesso a dados - DAL. Nosso objetivo será criar o mapeamento ORM usando o LINQ to SQL para abstrair o acesso e a persistência dos dados. Fazendo assim não temos que nos preocupar com comandos SQL pois iremos trabalhar com objetos mapeados.

Clique com o botão direito sobre o projeto DAL na janela Solution Explorer e selecione Add -> New Item;

A seguir selecione Data -> LINQ to SQL Classes e informe o nome Cadastro.dbml clicando no botão Add;

O descritor LINQ será aberto. Abra a janela Server Explorer e exiba a conexão expandido o item Data Connections (Se a conexão com o banco de dados Cadastro.mdf não aparecer você deverá criá-la);

Expanda o item Tables e selecionando a tabela Usuarios arraste-a e solte-a no descritor LINQ;

A seguir clique no descritor LINQ com o botão direito e selecione a opção Show Methods Pane;

Agora expanda o item Stored Procedures e arraste e solte a stored procedure registraUsuario para o panel de métodos conforme a figura abaixo:

Com isso mapeamos a tabela Usuarios e a stored procedure usando o LINQ to SQL de forma que podemos abstrair os comandos SQL e os objetos ADO .NET e iremos trabalhar com o objeto Usuario e suas propriedade e o método registraUsuario;

Definindo a camada de negócios - BLL (o recheio do bolo)

Já podemos definir a camada de negócios. Aqui deve ficar toda a lógica do seu negócio que para o nosso exemplo será bem simples.

Irei definir apenas algumas propriedades e dois métodos para realizar a tarefa de registrar um usuário na base de dados.

Vamos alterar o nome da classe Class1.cs para Registro.cs e definir o seguinte código nesta classe:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;

namespace BLL
{
    public class Registro
    {
        string _nome;
        string _email;
        string _senha;

        public string Nome
        {
            get { return _nome;}
            set { _nome = value; }
        }
        public string Email
        {
            get { return _email; }
            set { _email = value; }
        }
        public string Senha
        {
            get { return _senha; }
            set { _senha = value; }
        }
        
        public void Inserir()
        {
            CadastroDataContext dc = new CadastroDataContext();
            dc.registraUsuario(1, _nome, _email, _senha);
        }

        public string CriptDescript(string Texto)
        {
            string crip = string.Empty;
            const int Chave = 1708;
            foreach (char character in Texto)
            {
                int charCode = (int)character;
                char cripChar = (char)(charCode ^ Chave);
                crip += cripChar.ToString();
            }
            return crip;
        }

    }

}
A classe Registro esta usando a referência ao projeto DAL e também o namespace BLL;

Nesta classe definimos:

- 3 propriedades : Nome, Email e Senha

- O método Inserir que cria uma instância do contexto (CadastroDataContext) para poder
usar o método registraUsuario passando os parâmetros : tarefa, nome, email e senha;

- O método CriptDescript() que efetua a cifragem da senha

Definindo a camada de interface - UI (a cobertura do bolo)

Vamos agora definir a camada de interface (UI) definindo na página Default.apx um formulário para o usuário informar o nome , email e a senha e um botão para disparar um evento que vai chamar o método para inserir o usuário.

Inclua na página Default.aspx um componente ScriptManager, 1 controle UpdatePanel, 3 TextBox , 1 Button e 1 Label conforme o leiaute abaixo:

Para validar os dados informados vamos usar os componentes : RequiredFieldValidator e RegularExpressionValidator. Veja abaixo como deve ficar o código da página Default.aspx;

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        .style1
        {
            font-family: "Trebuchet MS";
        }
    </style>
</head>
<body>
    <form id="form2" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                 <table align="center" style="height: 118px; width: 534px">
                 <tr>
                  <td>
                   <asp:Label ID="lblfname" runat="server" Text="Nome :" CssClass="style1"></asp:Label></td>
                   <td>
                    <asp:TextBox ID="txtnome" runat="server" Width="283px"></asp:TextBox>
                               <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
                                   ControlToValidate="txtnome" ErrorMessage="O nome deve ser informado !">*</asp:RequiredFieldValidator>
                           </td>
                         </tr>
                         <tr>
                <td>
                <asp:Label ID="lblemailid" runat="server" Text="Email :" CssClass="style1"></asp:Label>
                </td>
                  <td>
                    <asp:TextBox ID="txtemail" runat="server" Width="282px"></asp:TextBox>
                                  <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" 
                                      ControlToValidate="txtemail" ErrorMessage="Email obrigatório !">*</asp:RequiredFieldValidator>
                                  <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" 
                                      ControlToValidate="txtemail" ErrorMessage="Email inválido !" 
                                      ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*</asp:RegularExpressionValidator>
                 </td>
                 </tr>
                 <tr>
                 <td>
                 <asp:Label ID="lblpassword" runat="server" Text="Senha :" CssClass="style1"></asp:Label>
                </td>
                  <td>
                    <asp:TextBox ID="txtpassword" runat="server" TextMode="Password"></asp:TextBox>
                                  <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" 
                                      ControlToValidate="txtpassword" ErrorMessage="A senha é obrigatória !">*</asp:RequiredFieldValidator>
                                  <asp:RegularExpressionValidator ID="RegularExpressionValidator2" runat="server" 
                                      ControlToValidate="txtpassword" ErrorMessage="Senha Inválida !" 
                                      ValidationExpression="\w{6,10}">*</asp:RegularExpressionValidator>
                </td>
                </tr>
                <tr>
                <td class="style1"> &nbsp;</td>
                <td>
                    <asp:Button ID="Btnregistrar" runat="server" onclick="Btnregistra_Click" 
                        Text="Registrar Usuário" />
                </td>
               </tr>
                <tr>
                <td class="style1" colspan="2">
                   <asp:Label ID="lblmsg" runat="server" ForeColor="Blue"></asp:Label>
                </td>
               </tr>
               </table>    
            </ContentTemplate>
        </asp:UpdatePanel>       
</div>
 </form>
</body>
</html>

Vejamos agora como deve ficar o código do arquivo code-behind Default.aspx.cs onde no evento Click do botão de comando vamos incluir o código abaixo:

Nota: Observe que fazemos referência ao projeto BLL;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BLL;
public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
        }
    }
    protected void Btnregistra_Click(object sender, EventArgs e)
    {
         BLL.Registro r = new BLL.Registro();

         r.Nome = txtnome.Text;
         r.Email = txtemail.Text;
         try
         {
             r.Senha = r.CriptDescript(txtpassword.Text);
             r.Inserir();
             lblmsg.Text = "Usuário registrado com sucesso";
         }
         catch (Exception ex)
         {
             lblmsg.Text = "Erro ao registrar usuário : " + ex.Message;
         }
    }
}

O código cria uma instância da classe Registro que esta na camada de negócios (BLL) e recebe os valoers informados para nome, email e senha;

Efetua a cifragem da senha através do método CriptDescript() e em seguida chama o método Inserir() que usa a stored procedure para gravar os dados do usuário;

Para executa a solução devemos definir antes qual o projeto que deverá ser iniciado. Clique com o botão direito sobre a Solução e selecione a opção Properties;

Na janela que aparece defina o Startup Project como sendo o projeto web : _webCamadaUI conforme abaixo e clique em OK;

Agora executando a solução teremos a página Default.aspx exibida conforme abaixo. Informando os valores e clicando no botão de comando veremos a mensagem que o usuário foi incluído com sucesso;

Se abrirmos a tabela para conferir veremos que os dados realmente foram persistidos através do LINQ to SQL que realizou o mapeamento ORM;

E dessa forma vimos como criar uma aplicação web em camadas usando LINQ to SQL.

Notou que não foi preciso usar os objetos da ADO .NET como Connection, Command, Adapter, Datasets ou DataReader ?

Notou que não precisamos usar no código nenhuma instrução SQL ? Apenas usamos a stored procedure mapeada pelo LINQ to SQL.

Pegue o projeto completo aqui : App3Camadas.zip

Aguarde mais artigos sobre LINQ.

Referências:


José Carlos Macoratti