Librería para interceptar métodos con soporte para reintentos, validaciones y medición de tiempo.
$ dotnet add package Interceptor.AOPUna librería ligera y extensible para aplicar Aspect-Oriented Programming (AOP) en aplicaciones .NET, usando interceptores automáticos basados en DispatchProxy.
Ideal para centralizar lógica transversal como reintentos, validaciones, cacheo, auditoría, y manejo de errores sin contaminar la lógica de negocio.
✔️ Soporte para métodos síncronos y asincrónicos (Task, Task<T>)
✔️ Decoración por atributos: fácil de aplicar, simple y expresiva, sin modificar código existente
✔️ Interceptores desacoplados y extensibles
✔️ Soporte para ILogger<T>, IMemoryCache y IOptions<T>
✔️ Ideal para microservicios, APIs, backend robusto
✔️ Integración lista para DI con Interceptor.AOP.AspNetCore
dotnet add package Interceptor.AOPservices.AddSingleton(provider =>
{
var logger = provider.GetRequiredService<ILogger<ProcesarDatosService>>();
var memoryCache = provider.GetRequiredService<IMemoryCache>();
// Instancia real del servicio
var real = new ProcesarDatosService(logger);
// Proxy con interceptor
return ProxyFactory.Create<IProcesarDatosService>(
real,
logger,
memoryCache,
new InterceptorOptions
{
EnableRetries = true,
EnableValidation = true,
EnableTiming = true
});
});public interface IProcesarDatosService
{
[Audit("ProcesarArchivo", LogInput = true)]
[Retry(3, 200)]
[Fallback("FallbackProcesarArchivo")]
[MeasureTime]
[Validate]
[Cache(60)]
int ProcesarArchivo(int number);
// El método fallback puede opcionalmente recibir la excepción lanzada
int FallbackProcesarArchivo(int number, Exception? ex = null);
}public class ProcesarDatosService : IProcesarDatosService
{
private readonly ILogger<ProcesarDatosService> _logger;
public ProcesarDatosService(ILogger<ProcesarDatosService> logger)
{
_logger = logger;
}
public int ProcesarArchivo(int number)
{
_logger.LogInformation("📊 Calculando algo con {number}", number);
if (number < 0) throw new Exception("Valor negativo no permitido");
return number * 10;
}
public int FallbackProcesarArchivo(int number, Exception? ex = null)
{
_logger.LogWarning("⚠️ Fallback ejecutado para {number}. Excepcion: {ex}", number, ex?.Message);
return -1;
}
}| Decorador | Description | |
|---|---|---|
| 📝 | [Audit] | Auditoría flexible: entrada, salida y manejo de excepciones con contexto |
| 🔁 | [Retry(n, delayMs)] | Reintenta el método n veces (opcional espera entre intentos en milisegundos y filtrado por tipos de excepción) |
| 🛡️ | [Fallback("...")] | Llama a otro método si el actual falla |
| ⏱️ | [MeasureTime] | Logea cuánto tarda la ejecución del método |
| 🧪 | [Validate] | Validaciones automáticas con DataAnnotations |
| 🔐 | [Cache(n)] | Cachea el resultado por n segundos (solo para Task<T> y métodos síncronos) |
El atributo [Audit] permite registrar entrada, salida y errores con granularidad y contexto funcional:
[Audit]
public Task<string> ObtenerClientesAsync() { ... }➡️ Registra entrada, salida y errores automáticamente.
[Audit("ProcesarArchivo")]
public void ProcesarArchivo(string path) { ... }➡️ Aparece en logs como: 📥 Entrada en ProcesarArchivo 📤 Salida de ProcesarArchivo ❌ Error en ProcesarArchivo (Auditable)
[Audit(LogInput = false, LogOutput = false, LogError = true)] // Solo errores[Audit(Contexto = "Importación", LogOutput = false)] // Entrada + error[Audit(LogInput = false, LogOutput = true, LogError = false)] // Solo salidaPermite reintentar un método si lanza una excepción.
[Retry(3, 200)]
public void ProcesarArchivo() { ... }➡️ Reintenta hasta 3 veces antes de fallar. Con delayMs > 0 espera ese tiempo entre intentos.
También podés indicar qué tipos de excepción disparan el reintento:
[Retry(3, ExceptionTypes = new[] { typeof(HttpRequestException) })]
public void LlamarApi() { ... }En este caso solo se reintenta si se lanza HttpRequestException.
Ideal cuando interactuás con servicios externos, bases de datos o archivos inestables.
Define un método de respaldo si el original lanza excepción después de los reintentos.
[Fallback("ProcesarArchivoFallback")]
public void ProcesarArchivo() { ... }
public void ProcesarArchivoFallback(Exception ex) { ... }➡️ Si ProcesarArchivo() falla, se ejecuta ProcesarArchivoFallback() automáticamente y recibe la excepción lanzada.
Registra cuánto tarda en ejecutarse un método.
[MeasureTime]
public void CalcularEstadisticas() { ... }➡️ Logea automáticamente algo como:
⏱️ CalcularEstadisticas ejecutado en 215msAplica validaciones usando [Required], [Range], etc. sobre modelos.
[Validate]
public void GuardarCliente(ClienteModel cliente) { ... }
public class ClienteModel
{
[Required]
public string Nombre { get; set; }
}➡️ Si cliente.Nombre es null, lanza ValidationException.
Guarda el resultado de un método por X segundos.
[Cache(60)]
public async Task<string> ObtenerDatos() => "Desde API";➡️ Durante 60 segundos, ObtenerDatos() devuelve la misma respuesta (usando IMemoryCache).
⚠️ Solo válido para métodos síncronos o Task<T>. No se aplica a Task (sin retorno).