What is aspect-oriented programming, and how do you do it in .NET?

C# Architecture Advanced 3–5 Yrs5+ Yrs Architecture 1 min read

Quick Answer

AOP factors out cross-cutting concerns — logging, caching, retry, transactions, validation — that would otherwise be scattered through every method. .NET has no built-in AOP; you achieve it with decorators, dynamic-proxy interceptors (Castle DynamicProxy), MediatR pipeline behaviours, ASP.NET Core filters/middleware, or a compile-time weaver (PostSharp/Metalama).

Aspect-oriented programming is about pulling out the concerns that cut across everything — logging, caching, retries, wrapping things in a transaction — so they're not copy-pasted into every method. .NET doesn't have a language feature for it, so I use decorators — wrapping the real service in one that adds the behaviour and delegates — or interceptors where the container generates a proxy around every call. In a CQRS setup, MediatR pipeline behaviours are the natural place: one behaviour adds logging around every handler, another validation, another a transaction. The key is that the aspect stays pure plumbing with no domain logic in it.

  • Decorator: wrap the real service in a class that adds the concern and delegates — explicit and testable.
  • Interceptor: the container generates a proxy that runs your interceptor code around every method — less code, more magic.
  • MediatR behaviours: one place to add logging/validation/transactions around every request handler.
  • Keep aspects free of business logic — they're plumbing.