artigo .net Magazine 45 - Camada de abstração de acesso a dados

Com esse artigo, pretendo ir além do uso trivial de Generics, mostrando uma aplicação prática e de quebra, também mostrar um pouco do uso de Reflection.

Clique aqui para ler esse artigo em PDF.

Clique aqui paraler todos os artigos desta edição

Boa Idéia

Camada de abstração de acesso a dados

Utilizando Generics e Reflection

 

O .NET Framework 2.0 trouxe diversas melhorias em relação à versão anterior, uma das novas funcionalidades mais comentadas com certeza é o Generics, que permite o uso de parâmetros para tipos em classes e métodos. Com o uso de Generics, quando um objeto é instanciado, é possível transmitir à classe um tipo que será utilizado por ela.

Essa funcionalidade é muito poderosa, porém na maioria dos exemplos que a descrevem, vemos apenas o uso do namespace Collections.Generic, o que é apenas uma parcela do que pode ser feito com essa funcionalidade.

Outra melhoria bastante poderosa do .NET Framework é o namespace System.Reflection, que permite buscar informações presentes nos assemblies e metadados em tempo de execução. Com esse artigo, pretendo ir além do uso trivial de Generics, mostrando uma aplicação prática e de quebra, também mostrar um pouco do uso de Reflection.

 

Objetivo do projeto

Quando decidi escrever um artigo sobre Generics, a primeira idéia que veio na minha cabeça foi o termo “reutilização de código”, queria mostrar uma forma de criar uma classe reutilizável e que pudesse ser chamada por qualquer tipo de objeto.

Comecei a pensar nas tarefas repetitivas nos projetos de informática. Uma das tarefas mais repetitivas que temos em termos de programação é a manipulação de dados, afinal na maioria esmagadora de projetos, teremos um banco de dados guardando informações presentes no sistema.

O mais comum atualmente é ter um projeto que já implementa métodos para chamadas ao banco de dados e toda parte de manipulação é realizada via Stored Procedures, a própria Microsoft disponibiliza o famoso SQLHelper presente no Application Blocks para isso (msdn2.microsoft.com/en-us/library/ms954827.aspx).

Outra forma de minimizar o trabalho de acesso a dados é utilizar ferramentas como o NHibernate (www.hibernate.org/343.html), que permite que você se preocupe somente em criar as classes e ele faz toda parte de integração com o banco de dados. Optei por fazer algo “parecido” com o NHibernate.

Lembrei de um projeto que fiz por volta de 2001, quando ainda trabalhava com o nosso tão adorado Visual Basic 6 e ADO. Na época, criei um ActiveX que já fazia automaticamente inserts, updates etc., sempre baseados em informações presentes nos formulários. É claro que as limitações da ferramenta me obrigavam a guardar informações sobre o tipo de dado presente no campo em propriedades como a Tag e até no próprio nome do componente. Mas até que funcionava bem!

Foi pensando nesse projeto que escrevi esse artigo, vamos criar um componente de manipulação de dados que faça todo trabalho “sujo” sozinho. Dessa forma o desenvolvedor não precisará se preocupar em criar SQL, ou Stored Procedures no banco de dados, pois ao instanciar o componente, todos os métodos de manipulação de dados já estarão implementados e prontos para serem utilizados.

Os métodos que decidi implementar foram os seguintes: Insert, Update, Delete, buscar um registro a partir do código e buscar uma lista de registros a partir de um filtro.

 

Importante: O foco desse artigo é didático, já existem diversas ferramentas, tanto comerciais quanto gratuitas, que possuem as mesmas funcionalidades que usaremos nesse projeto. É possível que com algumas melhorias ele possa ser utilizado para fins comerciais, mas não vou me preocupar com detalhes como manipulação de exceções, caracteres especiais, SQL Injection, suporte para diferentes tipos de bancos de dados etc. O projeto desenvolvido aqui é puramente educacional.

 

Esse projeto foi escrito para funcionar apenas com SQL Server e foi testado apenas no SQL Server 2005.

 

ADO.NET

Para deixar o código fácil de ser manipulado e o menos confuso possível, decidi separar a parte de ADO.NET em uma outra classe. Para os métodos que implementaremos, precisamos de uma classe auxiliar que realize as seguintes funções utilizando ADO.NET:

·Executar uma inserção e buscar o código do registro inserido;

·Executar uma query e buscar os dados retornados;

·Executar uma query sem retorno de valores.

Não vou me ater a descrever essas funções agora, pois elas não são o foco principal desse projeto, mas estão descritas nos tópicos a seguir.

 

Obtendo detalhes relacionados ao banco a partir das classes

Como comentei anteriormente, o objetivo deste artigo é criar um componente que permita que o desenvolvedor possa escrever apenas o código das classes no projeto e não se preocupar com rotinas de manipulação de dados.

Para que isso aconteça o componente deve estar apto a gerar comandos SQL dinamicamente, e para isso, ele precisa ter acesso ao nome de tabelas, campos, tipo de campos etc. Caso essas informações estejam disponíveis no projeto, de uma forma que saibamos ler, temos condições de buscá-las utilizando Reflection.

Portanto devemos definir algumas regras que devem ser seguidas pelo desenvolvedor ao criar o projeto.

1.Cada tabela deve ter uma classe correspondente no projeto;

2.O nome da classe deve ser idêntico ao nome da tabela no banco de dados;

3.Cada instância da classe representará um único registro da tabela;

4.Cada campo da tabela deve ter uma propriedade correspondente na classe.

Para permitir que além de propriedades relacionadas com a tabela, outras propriedades possam estar presentes na classe, optei por utilizar um atributo para identificar as propriedades que sejam diretamente relacionadas com campos do banco de dados.

Outra funcionalidade muito importante é identificar a chave primária da tabela, assim poderia realizar updates e deletes com facilidade. Também optei por utilizar um atributo para identificar as propriedades que se referem à chave primária da tabela.

O atributo para identificação de propriedades relacionadas com campos, chamei de DataBaseField e o atributo para identificação da propriedade relacionada com a chave primária, chamei de DataBaseIDField.

 

Criando o projeto em si

Abra o Visual Studio 2005 e crie uma nova solução vazia (Blank Solution) chamada de “DBAbstraction”. Adicione um novo projeto do tipo Class Library chamado de “GenericDBClass” e exclua a classe que é criada por padrão no projeto.

Podemos começar a trabalhar no que será necessário para fazer a integração com o banco de dados. Como a identificação das propriedades relacionadas com campos da tabela será feita a partir de atributos customizados, a primeira programação a fazer é criar essas classes. Adicione uma nova classe no projeto chamada “DataBaseField.cs” e adicione o código descrito na Listagem 1.

 

Listagem 1. Classe DataBaseField

using System;

using System.Collections.Generic;

using System.Text;

 

namespace GenericDB

{

public class DataBaseField : Attribute { }

}

 

Como pode ser visto, essa classe precisa apenas herdar de Attribute, assim ela pode ser utilizada como atributo. Agora vamos criar o atributo para identificar a chave primária. Adicione uma nova classe no projeto chamada “DataBaseIDField.cs” e adicione o código descrito na Listagem 2. Como a chave primária também representa um campo, essa classe herda de DataBaseField.

 

Listagem 2. Classe DataBaseIDField

using System;

using System.Collections.Generic;

using System.Text;

 

namespace GenericDB

{

   public class DataBaseIDField : DataBaseField { }

}

 

Armazenando detalhes dos campos

A base do projeto é a geração dinâmica de comandos SQL portanto, precisava ter uma forma de guardar detalhes dos campos da tabela sendo manipulada. Para isso, crie uma classe chamada “DatabaseFieldDetail.cs” para armazenar as informações dos campos, como podemos ver na Listagem 3.

 

Listagem 3. Classe para armazenar informações dos campos

using System;

using System.Collections.Generic;

using System.Text;

using System.Reflection;" [...] continue lendo...

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados