ASP .NET - Trabalhando com duas camadas com C#


No mundo dos grandes negócios e das aplicações corporativas é muito como comum se ouvir falar em arquitetura de software, camada de negócios, camada de dados, e assim por diante. Para o desenvolvedor que atua sozinho ou para pequenas equipes a ênfase esta em se terminar o serviço o mais rápido possível e decisões quanto a arquitetura da aplicação são freqüentemente deixadas de lado.

No entanto a utilização de camadas em uma arquitetura de software é muito simples de implementar e fornece grandes benefícios. Sua utilização permite abstrair toda a lógica de acesso dados em um conjunto de classes e fornece uma interface consistente, além de facilitar a manutenção, a portabilidade e a escalabilidade da aplicação.

Mas parece que quando se fala em camadas há uma certa hesitação ou confusão quanto a quantidade de camadas usar e como distribuí-las em uma aplicação pois não existe uma receita pronta que sirva como um modelo para todas as aplicações, pois cada projeto tem suas particularidades que devem ser analisadas em detalhes antes de tomar uma decisão.

Dessa forma se sua aplicação possui uma lógica de negócio complexa talvez houvesse a necessidade de criar uma arquitetura em 3 camadas com uma camada de negócios (Business Logic Layer), uma camada de acesso a dados(Data Access Layer) e a camada de apresentação (UI). No entanto se sua aplicação é uma aplicação simples uma arquitetura com 2 camadas com uma camada de acesso a dados e a camada de apresentação seja o bastante. Vemos abaixo um esquema dessas duas propostas:

Na arquitetura com 2 camadas a camada de apresentação chama diretamente a camada de acesso a dados.

Na arquitetura com 3 camadas a camada de apresentação chama a camada de negócios que chama a camada acesso a dados.

Observe que em nenhum dos casos estamos fazendo o acesso direto ao banco de dados pois sempre estamos trabalhando com uma camada de acesso a dados.

Usando uma camada de acesso a dados(DAL) podemos retornar um DataSet ou DataTable e tratar o retorno na camada de apresentação.

Com uma camada de negócios (BLL) podemos efetuar efetuar uma validação de regra de negócio e em seguida passar os objetos para a camada de apresentação.

Estes cenários são perfeitamente realistas e aplicáveis e ambos reduzem a quantidade de código e apresentam um melhor desempenho do que a arquitetura one-button-click, aquela velha técnica de colocar um botão de comando e no seu evento Click incluir todo o código necessário para validação , acesso a dados, etc.

Nota: Uma discussão sobre se devemos trabalhar com objetos do domínio da aplicação ou com DataSets ou DataTables foge ao escopo deste artigo.

Neste artigo eu vou tratar do modelo em duas camadas por ser mais simples de se adotar e usar, e por atender uma grande variedade de pequenas aplicações.

Eu vou tentar convencê-lo de que criar uma camada de acesso a dados é uma tarefa bem simples: basta criar algumas classes que expõe métodos públicos.

Em aplicações ASP .NET essas classes podem ser colocadas na pasta App_Code, uma pasta especial onde as classes são compiladas automaticamente. Em aplicações VB .NET basta criar uma classe com método públicos. Em ambos os casos as classes conterão tantos métodos quanto as ações que a aplicação necessita realizar com o banco de dados.

Para exercitar imagine as ações que precisamos realizar com uma tabela de dados:

Geralmente estas seriam as ações principais exigidas em uma aplicação padrão de acesso a dados.

Criando uma camada de acesso a dados (DAL)

Agora vamos partir para a prática criando nossa camada de acesso a dados. Antes vamos definir um cenário e os recursos que iremos usar:

- Vamos criar uma aplicação ASP .NET usando a linguagem C# ;
- Vamos usar o Visual Web Developer 2008 Express Edition;
- Vamos usar o SQL Server 2005 Express Edition;
- Vamos usar o banco de dados Macoratti.mdf;

O banco de dados Macoratti.mdf é uma cópia simplificada do banco de dados Northwind.mdf e usada para os propósitos didáticos deste artigo. Ele foi criado no SQL Server 2005 Express usando a ferramenta Management Studio Express. Veja abaixo as tabelas e o diagrama do banco de dados exibindo o relacionamento entre as tabelas:

Vamos iniciar abrindo o VWD 2008 e criando um novo web site no menu File-> New web site;

Selecione o template ASP .NET web Site , a Location File System e a linguagem C# e defina o nome do web site 2CamadasWeb;

Usando o DataBase Explorer vamos definir uma conexão com o banco de dados Macoratti.mdf de a forma que a string de conexão seja adicionada no arquivo web.config da seguinte forma:

   <connectionStrings>
        <add name="MacorattiConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Macoratti;Integrated Security=True"
            providerName="System.Data.SqlClient" />
    </connectionStrings>

Na seção connectionString temos:

Defina a string de conexão vamos criar a classe onde iremos criar os métodos para a camada de acesso a dados. No menu WebSite -> Add New Item, selecione o template Class e informe o nome categoriaDAL.cs;

Clique no botão Sim para confirmar o arquivo na pasta App_Code;

Vamos considerar a criação de métodos para implementar as funcionalidades básicas previstas para a tabela Categorias começando com a obtenção de todos os registros através do método getCategorias():

Não devemos esquecer de declarar o namespace System.Data.SqlClient :

using System.Data.SqlClient;

A seguir temos o código do método getCategorias() que retorna todas as categorias cadastradas na tabela Categorias:

public static DataTable GetCategorias()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MacorattiConnectionString"].ConnectionString))
        {
            conn.Open();

            SqlCommand cmd = new SqlCommand("SELECT * FROM Categorias", conn);

            DataTable tbl = new DataTable();
            tbl.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection));

            return tbl;
        }
    }

Note que criamos um método estático, dessa forma não precisamos instanciar a classe para chamar o método.

- Usamos a instrução using que define um escopo fora do qual os objetos ou recursos usados são descartados. No código estamos efetuando uma conexão com o banco de dados usando a string de conexão contida no arquivo web.config e obtida através da classe ConfigurationManager;
- Criamos um objeto SqlCommand onde definimos a instrução SQL - SELECT * FROM Categorias e usamos a conexão aberta;
- Criamos um objeto DataTable e executamos o comando e o retorno é carregado (Load) no objeto DataTable;
- A instrução using faz com que o objeto SqlConnection seja fechado e a memória liberada permitindo assim a sua reutilização;

Neste momento já temos uma camada de acesso a dados para as categorias funcional com um método definido. Para testar selecione a página Default.aspx e inclua um componente GridView na página alterando o seu ID para gdvCategorias;

A seguir no arquivo code-behind, Default.aspx.cs inclua o seguinte código no evento Load() da página:

  protected void Page_Load(object sender, EventArgs e)
    {
        gdvCategorias.DataSource = categoriaDAL.GetCategorias();
        gdvCategorias.DataBind();
    }

Observe como o código ficou limpo. Nele estamos chamando o método GetCategorias() da classe categoriaDAL.

Como é retornado um DataTable já estamos vinculando o retorno para ser exibido no GridView.

Executando o projeto iremos obter:

Podemos melhorar o método incluindo um tratamento de erros básico somente para não deixar o código escancarado. O método getCategorias() ficariam assim:

    public static DataTable GetCategorias()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MacorattiConnectionString"].ConnectionString))
        {
            try
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("SELECT * FROM Catgorias", conn);
                DataTable tbl = new DataTable();
                tbl.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection));
                return tbl;
            }
            catch (SqlException sqlex)
            {
                throw new Exception ("Erro SQL ao acessar Categorias" + sqlex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception("Erro ao acessar Categorias" + ex.Message);
            }
        }

O código em negrito foi incluído justamente para tratar erros de SQL e qualquer outra exceção que ocorrer durante a operação.

Veja que estou lançando (throw) as exceções, logo tenho que capturá-las na interface alterando o código para :

   protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            gdvCategorias.DataSource = categoriaDAL.GetCategorias();
            gdvCategorias.DataBind();
        }
        catch (Exception ex)
        {
            lblErro.Text = "Erro ao acessar dados : " + ex.Message;
        }
    }

 

A página Default.aspx deve também ser alterada pela inclusão do controle Label com ID=lblerro para exibir a mensagem de erro.

Aguarde a continuação do artigo onde irei  criar os demais métodos da camada de acesso a dados categoriaDAL.

Eu sei é apenas ASP .NET, mas eu gosto...

Referências:


José Carlos Macoratti