Interfaces e Generics numa generalização de uma DAL
Nas ultimas semanas tenho ponderado e escrito algum código relativo ao gerador de código. Até agora consegui uma interface básica com uma treeview para navegar pelos objectos e um painel de propriedades para editar as propriedades dos objectos que defini. Muito arcaico mas ainda é só uma base. Pelo menos já gera o código dos business objects como utilizo, e escreve a configuração para um ficheiro XML, usando uma classe de serialização que eu já tinha.
Agora ando a pensar e preparar a DAL, que é talvez a parte mais complexa em termos de estrutura. É mais complexo, em especial, devido à modulariedade que desejo que tenha. Em especial, o conjunto de requisitos que desejo para a DAL são:
Basicamente, necessito de um género de framework para a DAL. Modelei o conceito no papel e verifiquei que iria ter que prototipar alguns conceitos para garantir o funcionamento e aperfeiçoar o método. Em especial, necessitei de testar e verificar as limitações dos generics e interfaces no C#.
O Modelo / Código
Aproveitei o snippet compiler para escrever algum código simples para testar o esquema de interfaces e generics. Imaginei que o meu gerador de código deveria gerar apenas as classes da DAL com os métodos para manipular os dados, sem ter de preocupar com o sistema de base de dados a utilizar. Compreendo que a geração de queries pode ser problemático (há ligeiras variações de sintaxe entre sistemas), mas é algo que irei procurar generalizar e resolver.
Á partida (e já era algo que tinha de outros projectos) tenho uma classe por tipo de base de dados de accesso a dados que expõe métodos de obtenção (GetItem, GetList), escrita (Save) preenchimento (Fill) de objectos na base de dados. Geralmente os métodos aceitam como parametros a query e a connection string e devolvem os objectos preenchidos ou códigos de successo. Os métodos tratam de abrir a ligação, loggar o inicio da operação, executar a query, preencher o objecto de retorno (loggando sucesso ou erros) e devolvendo o resultado. As operações são as mais “básicas” e servem para muitos tipos de operações (por exemplo, porque o meu “Save” é baseado num ExecuteNonQuery(), este serve normalmente para Inserts, Updates, e Deletes). Naturalmente, para garantir a modulariedade, as várias classes tem de ter a mesma interface.
Da mesma forma que o sistema deve permitir o acesso a dados, com uma class por tipo de base de dados, também deverá ter para cada tipo de repositório de registos (log). Naturalmente, devem ter a mesma interface.