English | Español
BeyondNet.Aop is a high-performance Aspect-Oriented Programming (AOP) framework for .NET 10. It allows you to cleanly separate cross-cutting concerns (like logging, error handling, retries, etc.) from your core business logic using native .NET DispatchProxy with heavy caching optimizations.
- High Performance: Uses
ConcurrentDictionaryto cache reflection calls and dynamic expression compilation (O(1) lookups). - Clean Code: Strict naming conventions and semantic exceptions.
- Native .NET: Built on top of
System.Reflection.DispatchProxywithout requiring complex post-compilation weaving tools. - Extensible: Easily plug in custom loggers or evaluation engines.
- Observability: Built-in Serilog integration with structured logging and execution context propagation.
- DI Integration: Seamless integration with Microsoft.Extensions.DependencyInjection.
The framework is organized into modular packages:
BeyondNetCode.Shell.Aop # Core abstractions (IAspect, IJoinPoint, AspectExecutor)
BeyondNetCode.Shell.Aop.Aspects # Pre-built aspects (Retry, Logger, Advice)
BeyondNetCode.Shell.Aop.DispatchProxy # Proxy creation using DispatchProxy
BeyondNetCode.Shell.Aop.Aspects.Logger # Common.Logging integration
BeyondNetCode.Shell.Aop.Aspects.Logger.Serilog # Serilog integration with structured logging
BeyondNetCode.Shell.Aop.DI # Dependency Injection extensions
# Core library
dotnet add package BeyondNetCode.Shell.Aop
# Pre-built aspects
dotnet add package BeyondNetCode.Shell.Aop.Aspects
# Serilog integration (recommended)
dotnet add package BeyondNetCode.Shell.Aop.Aspects.Logger.Serilog
# DI installer
dotnet add package BeyondNetCode.Shell.Aop.DI[AttributeUsage(AttributeTargets.Method)]
public class MyLogAttribute : AbstractAspectAttribute
{
public string Message { get; set; }
}public class MyLogAspect : OnMethodBoundaryAspect<MyLogAttribute>
{
protected override void OnEntry(IJoinPoint joinPoint)
{
var attr = GetAttribute(joinPoint);
Console.WriteLine($"Method {joinPoint.MethodInfo.Name}: {attr.Message}");
}
}public interface IMyService
{
[MyLog(Message = "Starting operation")]
Task<Result> DoWorkAsync();
}services.AddAopAspects(typeof(IMyService).Assembly);Implement IPointCut to control when aspects are applied:
public class MyPointCut : IPointCut
{
public bool CanApply(IJoinPoint joinPoint, Type aspectType)
{
// Custom logic
}
}Use the Order property on attributes to control execution order:
[MyAspect(Order = 1)]
[AnotherAspect(Order = 2)]
void MyMethod() { }public class RetryAttribute : AbstractAspectAttribute
{
public int MaxRetries { get; set; } = 3;
public int BaseDelayMs { get; set; } = 1000;
}
public class RetryAspect : OnRetryAspect<RetryAttribute>
{
protected override bool CanRetry(IJoinPoint joinPoint, Exception ex)
{
return GetAttribute(joinPoint) is { } attr &&
attr.MaxRetries > 0;
}
}dotnet testSee CONTRIBUTING.md for GitFlow workflow and coding standards.
See VERSIONING.md for SemVer strategy.
Apache 2.0 - See LICENSE
See DISCLAIMER.md for original code authorship.