Olá!

O objetivo desse post é falar sobre POA (Programação orientada a aspecto) ou se preferir AOP (Aspect Oriented Programming) utilizando uma funcionalidade chamada Interceptors que por sua vez é provida por vários IoC containers.

O pré-requisito necessário para entender esse post é conhecer a teoria e prática de POA e IoC.

 

Iremos trabalhar em cima dessa solução, disponibilizada via GitHub:

https://github.com/slipmp/AOP

 

Código totalmente funcional, é baixar, compilar e rodar. Então vamos lá.

 

O que é um Interceptor?

Interceptor é o nome dado ao ato de você interceptar uma chamada via código, adicionando código antes e depois do método interceptado. Ou seja, os Interceptors são uma maneira de implementar POA via código.

No caso, utilizaremos Interceptors em IoC containers. Segue a lista usada de IoC na solução que disponibilizei via GitHub:

  • Castle Windsor: http://docs.castleproject.org/
  • Simple Injector: https://simpleinjector.codeplex.com/
  • Ninject: http://www.ninject.org/
  • Unity Application Block: http://msdn.microsoft.com/library/ff647202.aspx

 

Utilizarei apenas um dos containers acima como exemplo, mas todos eles estão apresentados na solução. Explicações do uso de cada um pode ser encontrado em suas respectivas documentações.

Utilizando Castle Windsor como exemplo – CastleWindsorIoCContainer.cs:

 

using Castle.Windsor;
using Castle.Core;
using Castle.MicroKernel.Registration;
using Castle.DynamicProxy;

public class CastleWindsorIoCContainer
{
public T Resolve<T>()
{
// Criando o container
var container = new WindsorContainer();

//Registrando o Interceptor, como qualquer outra dependência é registrada.
container.Register(
Component.For<IInterceptor>().ImplementedBy<CastleWindsorInterceptor>());

//Registrando uma dependência, adicionando o Interceptor para
todos os seus métodos.
container.Register(Component.For<IMeuServico>().
ImplementedBy<MeuServico>()
.Interceptors(InterceptorReference.
ForType<CastleWindsorInterceptor>()).Anywhere);

//Retornando a dependência
return container.Resolve<T>();
}
}

 

Ou seja, todos os métodos existentes dentro da implementação de IMeuServico, será interceptada pela implementação de CastleWindsorInterceptor.

Segue a implementação do interceptor: CastleWindsorInterceptor.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;

namespace AOP.Domain.Interceptor
{
public class CastleWindsorInterceptor : IInterceptor
{
#region IInterceptor Members

public void Intercept(IInvocation invocation)
{
try
{
Console.WriteLine("Castle Windsor Interceptor
Called on method " + invocation.Method.Name);

invocation.Proceed();

Console.WriteLine("Castle Windsor Interceptor
was successfully executed.");
}
catch(Exception ex)
{
Console.WriteLine("Castle Windsor An error has
occured calling Interceptor. Error: " + ex.Message);
}
finally
{
Console.WriteLine("Castle Windsor Interceptor - Finally");
}
}

#endregion
}
}

 

Perceba que o método interceptado está representado pela interface IInvocation e para chama-lo basta executar o método Proceed(). Pense nas infinitas possibilidades que essa magnifica ferramenta pode nos proporcionar com código limpo e centralização de responsabilidades tais como:

  • Validação em geral
  • Log (Banco de dados, envio de e-mail, etc.)
  • Instrumentação
  • Cache
  • Tratamento de exceção

Existe um nome dessa lista de possibilidades, chama-se “Cross-cutting concern” ou em português “características transversais/interesses transversais”.

Conclusão:

AOP com IoC container através de inspector é uma ferramenta poderosíssima!

Sei que todos esses conceitos não um pouco difíceis de se entender, mas quando bem utilizado pode trazer muitos benefícios para o seu código.

Minha dica é: depure o código desse projeto que está GitHub, ler o código é uma ótima maneira de entender o contexto.

 

Muito Obrigado!