Desenvolvimento - ADO.NET
Usando componentes com ADO.NET
Neste artigo vou abordar o desenvolvimento de aplicações na plataforma .NET em diversos ambientes como Web Application, Windows Application e Mobile Application que consumirão componentes integrados com o ADO.NET.
por Renato HaddadNeste artigo vou abordar o desenvolvimento de aplicações na plataforma .NET em diversos ambientes como Web Application, Windows Application e Mobile Application que consumirão componentes integrados com o ADO.NET.
A palavra chave é "Reaproveitamento de código", você deve ter visto muitas aplicações desenvolvidas que precisam fazer acesso a um banco de dados de diversos lugares, sendo que cada local contém a mesma rotina para acessar e retornar um DataSet. Até acho válido fazer desta forma se você não sabe como lidar com componentização, no entanto, a manutenção torna-se trabalhosa e insegura, por mais que você faça bem o copiar/colar.
Atualmente na plataforma .NET você precisa apenas de uma ferramenta para desenvolver o componente e criar todas as aplicações, é o Visual Sutio .NET. Quando você for instalar o componente criado, basta copiar no local de destino, ou seja, não existem mais os problemas de DLL Hell, conflitos com outras versões ou fabricantes de DLLs existentes.
Você já deve ter lido alguns artigos sobre desenvolvimento em N-tier (N-Camadas) onde é possível separar em 1, 2 ou 3 camadas. Nos exemplos apresentados aqui vou dividir as aplicações em apenas 2 camadas, sendo uma camada de acesso a dados que é o componente a ser desenvolvido e a camada de Interface que serão as aplicações Windows, Web e para um telefone celular.
Componente
O primeiro passo é criar o componente, o banco de dados a ser usado será o Northwind do SQL Server 2000 e as tabelas são Categories e Products. Abra o Visual Studio .NET e crie um novo projeto chamado clsDatabase do tipo Class Library, usando o Visual Basic .NET como linguagem.
Figura 1: Criação do Class Library
Selecione o menu Project / Add Class para criar uma classe chamada clsAcessoDados.vb e digite o código seguinte que contém duas funções para acessar as respectivas tabelas.
Imports System.Data.SqlClient Public Class clsAcessoDados Dim stringConn As String = "Initial Catalog=Northwind;Data Source=NomeDoServidor;User ID=sa" Public Function Categorias() As DataSet Dim conn As SqlConnection Dim sql As String = "Select * FROM Categories ORDER BY CategoryName" Dim da As SqlDataAdapter Dim ds As DataSet conn = New SqlConnection(stringConn) conn.Open() da = New SqlDataAdapter(sql, conn) ds = New DataSet() da.Fill(ds, "categorias") Return ds End Function Public Function Produtos(ByVal idCategoria As Integer) As DataSet Dim conn As SqlConnection Dim sql As String Dim da As SqlDataAdapter Dim ds As DataSet sql = "Select ProductName, UnitPrice, UnitsInStock FROM Products " sql &= "WHERE CategoryID=" & idCategoria sql &= " ORDER BY ProductName" conn = New SqlConnection(stringConn) conn.Open() da = New SqlDataAdapter(sql, conn) ds = New DataSet() da.Fill(ds, "produtos") Return ds End Function End Class
Note que a classe usada para acessar o SQL Server 2000 é a SqlClient, tornando mais rápido o acesso, pois é uma classe desenvolvida especificamente para acesso ao SQL Server 7 ou 2000. A função Categorias tem como objetivo selecionar todos os registros da tabela Categories, montar um DataAdapter chamado categorias e retornar um DataSet. Já a função Produtos tem como objetivo selecionar alguns campos da tabela Products onde o campo CategoryID seja igual ao parâmetro passado para função, em seguida monta um DataAdapter chamado produtos e retorna um DataSet. Como estas funções retornam um DataSet significa que independente da Interface a ser criada, o componente já está preparado para retornar os dados pesquisados, e como no .NET a forma de invocar e consumir um componente é transparente, você pode e deve usar isso em todas as chamadas dos controles que precisarem consumir estes dados. Após digitar o código, selecione o menu Build / Build Solution para compilar o componente. Dentro da pasta que você gravou o componente é criada uma pasta Bin com a DLL criada, e é justamente este arquivo que você deverá distribuir com a sua aplicação quando fizer o deployment.
Web Application
Uma aplicação feita para rodar na Internet é chamada de ASP.NET e a linguagem utilizada no nosso código será o Visual Basic .NET, mas nada o impede de utilizar o C# e consumir um componente feito em VB.NET ou o inverso também é válido. Crie um novo projeto chamado VSPJ do tipo ASP.NET Web Application e adicione um Web Form chamado consomeCompWeb.aspx contendo um ListBox chamado lstCategorias e um Datagrid chamado gridProdutos.
Figura 2: Estrutura dos controles nas páginas WEB
Para o controle lstCategorias, configure a propriedade AutoPostBack para True, pois toda vez que você selecionar uma categoria o código será disparado para preencher o Datagrid de produtos. Se o AutoPostBack estiver como False o código não será executado.
Para referenciar o componente criado selecione o menu Project / Add Reference, localize o respectivo arquivo clsDatabase.dll dentro da pasta Bin e clique no botão OK.
Figura 3: Referencie o componente a ser usado
Digite o código para carregar as categorias assim que a página for aberta. O comando IsPostBack verifica se foi dado um Post na página, ou seja, esse código será carregado apenas na primeira vez que a página for carregada, mesmo estando no evento Page_Load.
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Not IsPostBack Then "referencia o componente Dim comp As New clsDatabase.clsAcessoDados() "atribui as propriedades para o ListBox With Me.lstCategorias .DataTextField = "CategoryName" .DataValueField = "CategoryID" "monta e popula o ListBox .DataSource = comp.Categorias.Tables("categorias").DefaultView .DataBind() End With Me.gridProdutos.Visible = False End If End Sub
Explicação
Para referenciar um componente atribua o mesmo a uma variável e note que é utilizado o New NomeComponente.NomeClasse().
Dim comp As New clsDatabase.clsAcessoDados()
Para consumir a função existente na classe use a variável + ponto + nome da função. Como esta classe retorna um Dataset que contém um DataAdapter chamado categorias, então a origem (DataSource) deste ListBox é exatamente a tabela chamada categorias gerada pelo DataAdapter.
.DataSource = comp.Categorias.Tables("categorias").DefaultView
Digite o código no evento SelectedIndexChanged do ListBox lstCategorias para carregar o DataGrid com os produtos da respectiva categoria. Para facilitar, dê um duplo clique no lstCategorias que o evento é criado automaticamente.
Private Sub lstCategorias_SelectedIndexChanged (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstCategorias.SelectedIndexChanged "referencia o componente Dim comp As New clsDatabase.clsAcessoDados() Me.gridProdutos.Visible = True "monta e popula o datagrid With Me.gridProdutos .DataSource = comp.Produtos(Me.lstCategorias.SelectedItem.Value).Tables("produtos") .DataBind() End With End Sub
Preste atenção na origem (DataSource) do gridProdutos que contém o componente que invoca a função Produtos passando como parâmetro exatamente o código da categoria selecionada no lstCategorias. Esta função monta um DataAdapter chamado produtos que retorna o DataSet que será usado como origem do gridProdutos.
Defina esta página como padrão (Set As Start Page), salve o projeto, compile e execute no navegador (Ctrl + F5).
Figura 4: Execução da página WEB
Veja a quantidade de código que a sua página contém, é significativamente menor se todos os códigos de acesso a dados estivessem sido inseridos aqui, fora que ainda vamos consumir o componente em outras aplicações. Com isso, qualquer manutenção fica muito simples, fácil e ágil de se realizar.Mobile Application
Para você criar uma aplicação para ser executada em um telefone celular, é preciso instalar o Mobile Internet Toolkit que é um SDK a ser utilizado pelo Visual Studio .NET. Neste exemplo, vamos consumir o mesmo componente existente que retorna um DataSet. Dentro da mesma aplicação ASP.NET criada, selecione o menu Project / Add New Item e adicione um novo projeto chamado MobileDatabaseComp.aspx do tipo Mobile Web Form contendo dois formulários com o controle ObjectList, respectivamente objCategorias e objProdutos.
Figura 5: Formulário para telefone celular
Configure a propriedade LabelField do objCategorias para CategoryName e do objProdutos para ProductName. Insira o código para carregar as categorias no primeiro formulário. Note que o componente utilizado é o clsDatabase, ou seja, você não precisa criar todo o acesso a dados neste código porque isso já existe pronto no componente. Não reinvente a roda, planeje a aplicação para facilitar o desenvolvimento.
Private Sub Page_Load (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim comp As New clsDatabase.clsAcessoDados() Me.objCategorias.DataSource = comp.Categorias.Tables("categorias").DefaultView Me.objCategorias.DataBind() End Sub
Salve e execute no simulador do telefone celular (Microsoft Mobile Emulator 3.0). Caso você não tenha um simulador é possível rodar o código no navegador. Isso é fantástico porque o próprio Framework já reconhece qual o dispositivo que invocou a página e montar exatamente com o que ele suporta.
Figura 6: Execução da página no telefone celula
Quando você selecionar alguma categoria é executado o código que pesquisa todos os produtos e exibe no objProdutos.
Figura 7: Produtos da categoria selecionada
O próprio ObjectList é um controle inteligente que atribui um link ao item selecionado para poder exibir em outra página o restante das informações do produto.
Figura 8: Todas as informações do produto selecionado
Windows Application
Que tal utilizar os componentes em uma aplicação Windows? Esse é o objetivo deste exercício, reutilizar o máximo possível os códigos existentes. Abra o Visual Studio .NET e crie um projeto do tipo Windows Application chamado consomeCompWin com os seguintes controles: um ComboBox, um ListBox e um DataGrid, nomeados dropCategorias, lstProdutos e gridProdutos respectivamente.
Crie um código no evento Load do formulário para carregar o ComboBox de categorias. Veja que existe um tratamento de erro para a conexão com o componente, então como exercício insira nos códigos anteriores outras rotinas de tratamento de erros.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim comp As New clsDatabase.clsAcessoDados() Try Me.dropCategorias.DataSource = comp.Categorias.Tables("categorias").DefaultView Me.dropCategorias.DisplayMember = "CategoryName" Me.dropCategorias.ValueMember = "CategoryID" Catch myErr As System.Exception MessageBox.Show(myErr.ToString, "Alerts", MessageBoxButtons.OK) End Try End Sub Após selecionar uma categoria no ComboBox é preciso invocar o componente para popular o ListBox lstProdutos e o DataGrid gridProdutos. Private Sub dropCategorias_SelectedIndexChanged (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dropCategorias.SelectedIndexChanged Dim comp As New clsDatabase.clsAcessoDados() Try "captura a categoria selecionada Dim catIndex As Integer = Me.dropCategorias.SelectedIndex Dim catSelected As Integer = Me.dropCategorias.Items(catIndex)!CategoryID "monta o ListBox dos produtos Me.lstProdutos.DataSource = comp.Produtos(catSelected).Tables("produtos").DefaultView Me.lstProdutos.DisplayMember = "ProductName" "monta o DataGrid dos produtos Me.gridProdutos.DataSource = comp.Produtos(catSelected).Tables("produtos").DefaultView Catch myErr As System.Exception MessageBox.Show(myErr.ToString, "Alerts", MessageBoxButtons.OK) End Try End Sub
Após selecionar uma categoria no ComboBox é preciso invocar o componente para popular o ListBox lstProdutos e o DataGrid gridProdutos.
Salve e execute a aplicação.
Figura 9: Execução da aplicação Windows Form
Conclusão
Desenvolver uma aplicação bem estruturada proporcionando o uso de componentes é uma excelente maneira de você e a sua equipe trabalhar de forma organizada, modular, simples e objetiva. Procure planejar toda a aplicação antes de desenvolvê-la e veja as facilidades e as implicações de distribuir em camadas. Toda e qualquer manutenção a ser feita sempre será mais rápida. "No stress, think .NET"