Como trabalhar com CustomAttributes no Delphi
Os CustomAttributes são um recurso poderoso no Delphi que permite adicionar metadados às classes, métodos, propriedades ou até mesmo parâmetros. Essa funcionalidade foi introduzida para facilitar a criação de código mais dinâmico e robusto, ampliando as possibilidades de abstração e personalização.
A principal vantagem dos CustomAttributes é permitir que informações adicionais sejam associadas a elementos de código, sem interferir na lógica ou estrutura base. Esses metadados podem ser extraídos e utilizados em tempo de execução, permitindo comportamentos dinâmicos e adaptáveis.
Neste artigo, exploraremos como criar, utilizar e extrair informações de CustomAttributes no Delphi, passando por um exemplo prático para demonstrar como integrar essa funcionalidade em seus projetos.
O que são CustomAttributes no Delphi?
No Delphi, os CustomAttributes são implementados como classes derivadas de TCustomAttribute. Elas permitem que informações adicionais sejam anexadas a tipos, métodos, propriedades ou parâmetros. Essas informações, ou metadados, não afetam diretamente o comportamento do código em tempo de compilação, mas podem ser lidas em tempo de execução usando RTTI (Runtime Type Information).
Este recurso é amplamente utilizado em frameworks como ORM (Object-Relational Mapping), onde atributos customizados podem ser usados para mapear classes e propriedades a tabelas e colunas de banco de dados, por exemplo.
Como criar um CustomAttribute?
A criação de um CustomAttribute no Delphi é simples. Você precisa definir uma classe que herda de TCustomAttribute e adicionar os campos ou propriedades necessários para armazenar informações. Vamos ver um exemplo básico:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
type // Definindo um CustomAttribute para armazenar metadados de campos CampoAttribute = class(TCustomAttribute) private FNome: string; public constructor Create(const ANome: string); property Nome: string read FNome; end; // Implementação do construtor constructor CampoAttribute.Create(const ANome: string); begin FNome := ANome; end; |
Aqui, CampoAttribute permite associar um nome a um campo ou propriedade de uma classe.
Usando CustomAttributes em Classes
Depois de criado o atributo, ele pode ser associado a classes, propriedades ou métodos. Veja um exemplo de como utilizá-lo em uma classe:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
type [CampoAtribute('Tabela_Cliente')] TCliente = class private FId: Integer; FNome: string; public [CampoAtribute('Id_Cliente')] property Id: Integer read FId write FId; [CampoAtribute('Nome_Cliente')] property Nome: string read FNome write FNome; end; |
No exemplo acima, associamos o nome de uma tabela ao atributo da classe e nomes de colunas aos atributos das propriedades.
Extraindo CustomAttributes em Tempo de Execução
Para acessar os atributos definidos, utilizamos a RTTI. Abaixo, demonstramos como recuperar as informações de atributos associados a propriedades de uma classe:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
uses System.Rtti, System.TypInfo; procedure TForm1.ListarAtributos(Classe: TObject); var Contexto: TRttiContext; Tipo: TRttiType; Prop: TRttiProperty; Atributo: TCustomAttribute; begin Memo1.Lines.Clear; // Inicializando o contexto RTTI Contexto := TRttiContext.Create; try Tipo := Contexto.GetType(Classe.ClassType); for Prop in Tipo.GetProperties do begin for Atributo in Prop.GetAttributes do begin if Atributo is CampoAttribute then Memo1.Lines.Add(Format('Propriedade: %s, Atributo: %s', [Prop.Name, CampoAttribute(Atributo).Nome])); end; end; finally Contexto.Free; end; end; // Exemplo de uso procedure TForm1.Button1Click(Sender: TObject); var Cliente: TCliente; begin Cliente := TCliente.Create; try ListarAtributos(Cliente); finally Cliente.Free; end; end; |
O código acima percorre todas as propriedades da classe TCliente, buscando atributos do tipo CampoAttribute e exibindo suas informações.
Observações: Nos exemplos acima criamos um form no Delphi com apenas um Button e um Memo. Criamos uma unit App.CustomAtribute.pas com a classe CustomAtribute e outra unit para conter o objeto TCliente. Chamamos a unit de App.Cliente.
O exemplo percorre os atributos de TCliente, localiza o CampoAtribute e publica dentro de um Memo. Simples assim.
Aplicações Práticas
- Mapeamento de Banco de Dados: Atribuir nomes de tabelas e colunas diretamente no código para facilitar a integração com bancos de dados.
- Validação de Dados: Criar atributos que definem regras de validação específicas para campos.
- Serialização: Configurar atributos que indicam como as propriedades de uma classe devem ser serializadas.
Participe da Comunidade no Telegram
🚀 Quer continuar essa discussão e trocar ideias com outros desenvolvedores? Junte-se à nossa comunidade no Telegram! Lá, você pode comentar sobre o que achou deste artigo, tirar suas dúvidas e compartilhar suas experiências com Delphi e ainda discutir ou tirar suas dúvidas sobre os mais variados temas em uma comunidade com mais de 1.000 desenvolvedores.
🔗 Clique aqui para entrar na comunidade
Te vejo lá!
Conclusão
Os CustomAttributes no Delphi oferecem uma maneira poderosa de incorporar metadados ao seu código, permitindo maior flexibilidade e dinamismo em suas aplicações. Com sua utilização, é possível reduzir a rigidez do código e melhorar a organização e a manutenibilidade.
Experimente integrar CustomAttributes em seus projetos, e veja como este recurso pode transformar a forma como você estrutura e gerencia suas aplicações no Delphi.
Mais informações nesse link.
Adriano Santos