Programação Orientada a Aspectos (AOP - Aspect-Oriented Programming) | CSharp
- Programação Orientada a Aspectos (AOP - Aspect-Oriented Programming) | CSharp
A Programação Orientada a Aspectos (AOP - Aspect-Oriented Programming) é um paradigma que complementa a Programação Orientada a Objetos (OOP), permitindo separar preocupações transversais (cross-cutting concerns) — ou seja, funcionalidades que afetam múltiplas partes do sistema, como log, segurança, cache, auditoria, tratamento de exceções e transações.
Artigo: https://metalama.net/applications/aspect-oriented-programming
🧩 Conceito Básico
Em AOP, você define Aspectos (Aspects) — módulos que encapsulam comportamentos que atravessam várias classes ou métodos. Esses aspectos são “injetados” automaticamente no código principal, sem precisar modificar o código-fonte diretamente.
Termos principais:
- Aspect: unidade modular que contém código transversal (ex: log, segurança).
- Join Point: ponto de execução no código onde um aspecto pode ser aplicado (ex: chamada de método, acesso a propriedade).
- Advice: ação executada em um join point (antes, depois, ou ao redor da execução).
- Pointcut: expressão que define onde os advices devem ser aplicados.
- Weaving: processo de injeção dos aspectos no código — pode acontecer em tempo de compilação, carga, ou execução.
⚙️ AOP em C#
O C# não tem suporte nativo a AOP na linguagem base, mas há bibliotecas e frameworks que implementam o conceito.
🔧 Principais ferramentas:
-
PostSharp
-
O mais popular e maduro framework AOP para .NET.
-
Faz o weaving em tempo de compilação.
-
Permite definir aspectos com atributos e interceptar métodos facilmente.
-
Exemplo:
[Serializable]
public class LogAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine($"Entrando em {args.Method.Name}");
}
public override void OnExit(MethodExecutionArgs args)
{
Console.WriteLine($"Saindo de {args.Method.Name}");
}
}
public class Servico
{
[Log]
public void Executar()
{
Console.WriteLine("Executando serviço...");
}
} -
Saída:
Entrando em Executar
Executando serviço...
Saindo de Executar
-
-
Castle DynamicProxy / Windsor
- Usa injeção de dependência e proxy dinâmico para interceptar chamadas de método em tempo de execução.
- Muito usado com ASP.NET Core + Autofac.
Exemplo:
public class LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"Chamando {invocation.Method.Name}");
invocation.Proceed();
Console.WriteLine($"{invocation.Method.Name} terminou");
}
} -
AspectInjector
- Alternativa open-source ao PostSharp.
- Usa atributos e geração de código em tempo de compilação (via Roslyn).
-
Unity Interception / Autofac Interceptors
- Integrados a contêineres de injeção de dependência.
- Permitem aplicar aspectos ao resolver dependências.
🧠 Exemplo de Uso Real
Imagine que você quer aplicar log e tratamento de exceções em vários métodos sem repetir código:
[Log]
[HandleException]
public void ProcessarPagamento()
{
// Lógica principal
}
Os aspectos [Log] e [HandleException] podem ser aplicados a qualquer método, mantendo o código limpo e centralizando a lógica transversal.
🚀 Benefícios
✅ Reduz duplicação de código. ✅ Facilita manutenção e testes. ✅ Separa responsabilidades (SRP - Princípio da Responsabilidade Única). ✅ Permite adicionar ou remover comportamentos sem alterar código de negócio.
⚠️ Desvantagens
⚠️ Pode dificultar depuração (o comportamento é “injetado”). ⚠️ Adiciona complexidade e sobrecarga de desempenho se mal usado. ⚠️ Ferramentas como PostSharp podem ser pagas em versões avançadas.