Vamos agora estabelecer os objetivos do nosso Projeto.
§
Nossa ferramenta
irá criar uma classe DAL que será genérica, ou seja, não precisaremos criar
nenhuma classe DAL específica para cada classe Model em nosso projeto de teste.
Teremos apenas uma classe DAL que será acessada pelas classes Business;
§
Estabeleceremos
regras de acesso à essa classe DAL Genérica;
§
Estabeleceremos
regras para a criação das classes Model – forçando que nessas classes estejam
contidas funcionalidades ORM;
§
Estabeleceremos
regras para a criação de classes Business;
B) Deverá ser independente de banco de dados;
A) Não poderemos utilizar componentes de terceiros;
B) Usaremos somente recursos nativos do .Net Framework;
Nossa solução terá os seguintes projetos:

Ilustração 7
– Solução/Projetos
Os tipos de projetos
serão descritos na tabela abaixo:
|
Nome do
projeto |
Tipo de
Projeto |
|
Attributes |
Class Library |
|
BaseClasses |
Class Library |
|
DataBaseLib |
Class Library |
|
Interfaces |
Class Library |
|
TestProject |
Console Application |
Tabela 5 – Descrição dos tipos de projetos da solução
Este projeto conterá
todos os atributos que iremos utilizar em nossas classes model. Eles conterão
informações importantes para conseguirmos, por exemplo, mapear as propriedades
de uma classe com os campos de uma tabela, ou parâmetros de uma Stored
Procedure.
O primeiro atributo
que criaremos é o atributo que irá informar se a classe irá refletir uma tabela
ou parâmetros de Stored Procedure ou ambos.
Como temos três
opções de valor para este atributo, é de bom tom utilizarmos uma enumeração.
Então primeiramente criaremos um enum:
namespace GenDAL.Library.Attributes
{
public enum DataAccesType
{
None = 0,
StoredProcedure = 1,
DirectTableAcces = 2,
Both = 3
}
Com esse código
criamos um enum com as três opções citadas e mais uma, para utilizarmos como
padrão. Sendo assim, podemos criar nosso primeiro atributo:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class AttDataAccessType : Attribute
{
private DataAccesType _dataAccesType;
public DataAccesType DataAccesType
{
get { return _dataAccesType; }
set { _dataAccesType = value; }
}
public AttDataAccessType(DataAccesType dataAccessType)
{
this._dataAccesType = dataAccessType;
}
}
}
Como
podemos verificar, é muito simples criar atributos. Eles seguem a mesma regra
de uma classe comum com campos privados, propriedades e construtores. Para ser
um atributo a classe precisa herdar de
System.Attribute.
using System;
namespace GenDAL.Library.Attributes
{
public enum DataAccesType
{
None = 0,
StoredProcedure = 1,
DirectTableAcces = 2,
Both = 3
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class AttDataAccessType : Attribute
{
private DataAccesType _dataAccesType;
public DataAccesType DataAccesType
{
get { return _dataAccesType; }
set { _dataAccesType = value; }
}
public AttDataAccessType(DataAccesType dataAccessType)
{
this._dataAccesType = dataAccessType;
}
}
}
Aqui
temos algumas ponderações a fazer.
public enum ProcedureTypes
{
Insert = 0,
Update = 1,
SelectNoFilter = 2,
SelectFilter = 3,
Delete = 4
}
B) Quando trabalhamos com chamadas de
SP via código c#, precisamos utilizar objetos que informem dados relativos aos
parâmetros de SPs como a Direction, o DBType, o Size etc. Então deveremos
utilizar esse objetos como tipos de propriedades do nosso Atributo.
using System;
using System.Data;
namespace GenDAL.Library.Attributes
{
public enum ProcedureTypes
{
Insert = 0,
Update = 1,
SelectNoFilter = 2,
SelectFilter = 3,
Delete = 4
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple=true)]
public class AttParamProcDB : Attribute
{
private ProcedureTypes _tipoProcedure;
private string _procName;
private string _paramName;
private DbType _dbType;
private ParameterDirection _direction;
private int _paramSize;
public ProcedureTypes TipoProcedure
{
get { return _tipoProcedure; }
set { _tipoProcedure = value; }
}
public string ProcName
{
get { return _procName; }
set { _procName = value; }
}
public string ParamName
{
get { return _paramName; }
set { _paramName = value; }
}
public DbType DbType
{
get { return _dbType; }
set { _dbType = value; }
}
public ParameterDirection Direction
{
get { return _direction; }
set { _direction = value; }
}
public int ParamSize
{
get { return _paramSize; }
set { _paramSize = value; }
}
public AttParamProcDB(ProcedureTypes pProcTipo, string pProcName)
{
this._tipoProcedure = pProcTipo;
this._procName = pProcName;
}
public AttParamProcDB(ProcedureTypes pProcTipo, string pProcName, string pParamName)
{
this._tipoProcedure = pProcTipo;
this._procName = pProcName;
this._paramName = pParamName;
}
public AttParamProcDB(ProcedureTypes pProcTipo, string pProcName, string pParamName, DbType pDbType)
{
this._tipoProcedure = pProcTipo;
this._procName = pProcName;
this._paramName = pParamName;
this._dbType = pDbType;
}
public AttParamProcDB(ProcedureTypes pProcTipo, string pProcName, string pParamName, DbType pDbType, ParameterDirection pDirection)
{
this._tipoProcedure = pProcTipo;
this._procName = pProcName;
this._paramName = pParamName;
this._dbType = pDbType;
this._direction = pDirection;
}
public AttParamProcDB(ProcedureTypes pProcTipo, string pProcName, string pParamName, DbType pDbType, ParameterDirection pDirection, int paramSize)
{
this._tipoProcedure = pProcTipo;
this._procName = pProcName;
this._paramName = pParamName;
this._dbType = pDbType;
this._direction = pDirection;
this._paramSize = paramSize;
}
}
}
Basicamente
temos 6 propriedades que informarão o tipo de procedure, o nome da procedure, o
nome do parâmetro o DbType do parâmetro o ParameterDirection e o Size. Temos
também 5 construtores diferentes que inicializam conjuntos de propriedades
específicos.
O próximo
atributo a ser criado é o atributo que irá informar qual a tabela do banco de
dados que a classe está representando. Portanto teremos apenas uma propriedade
do tipo string que informará qual a tabela. Abaixo segue o código completo
deste atributo.
using System;
namespace GenDAL.Library.Attributes
{
[AttributeUsage(AttributeTargets.Class)]
public class AttTableName : Attribute
{
private string _tableName;
public string TableName
{
get { return _tableName; }
set { _tableName = value; }
}
public AttTableName(string pTableName)
{
this._tableName = pTableName;
}
}
}
O próximo
atributo é aquele que irá mapear as propriedades de uma classe com os campos da
tabela que ela representa. Neste atributo, informamos o nome do campo da tabela
e o tipo de dado deste campo:
using System;
using System.Data;
namespace GenDAL.Library.Attributes
{
[AttributeUsage(AttributeTargets.Property)]
public class AttFieldDB : Attribute
{
private string _fieldName;
private DbType _dbType;
public string FieldName
{
get { return _fieldName; }
set { _fieldName = value; }
}
public AttFieldDB(string pFieldName)
{
this._fieldName = pFieldName;
}
public AttFieldDB(string pFieldName, DbType pDbType)
{
this._fieldName = pFieldName;
this._dbType = pDbType;
}
}
}
Com
nossos atributos criados, vamos compilar o projeto para gerarmos uma Dll. É
importante observar a nomenclatura que demos na nossa Namaspace – ‘GenDAL.Library.Attributes’.
Essa Namespace será referenciada para utilizarmos os nossos atributos em nosso
projeto de classes ‘Model’.