PostSharp

PostSharp brings aspect-oriented programming to .NET. You write an aspect as a C# class, apply it with an attribute such as [Log], and a post-compilation step rewrites the assembly to insert the behavior. It is a commercial product with a limited free edition.

Paradigm: Aspect-Oriented Programming

What Makes PostSharp Special

  • Aspects are attributes. Applying [Log] to a method, a class or a whole assembly is enough. No pointcut language needs to be learned.
  • Compile-time weaving. After the C# compiler runs, PostSharp modifies the IL, so there is no proxy and no reflection at runtime.
  • Ready-made patterns. Base classes such as OnMethodBoundaryAspect and MethodInterceptionAspect cover logging, caching, retry, thread safety and transactions.
  • Attribute multicasting. One attribute can target many members at once: [assembly: Log(AttributeTargetTypes = "MyApp.Services.*")].
  • Architecture rules. It can also validate the design at build time, for example forbidding one namespace from using another.

Example: A logging aspect applied by attribute

using System;
using PostSharp.Aspects;

[PSerializable]
public class LogAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        Console.WriteLine($"Entering {args.Method.Name}");
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        Console.WriteLine($"Leaving {args.Method.Name}");
    }
}

public class Account
{
    private decimal balance;

    [Log]
    public void Deposit(decimal amount)
    {
        balance += amount;
    }
}

How It Works

  • LogAttribute derives from OnMethodBoundaryAspect, so PostSharp calls OnEntry and OnExit at the boundaries of any method it is applied to.
  • [PSerializable] lets PostSharp store the aspect instance in the compiled assembly.
  • [Log] on Deposit is the only change to business code. The method body still only updates the balance.
  • After compilation, calling Deposit(50) prints Entering Deposit and Leaving Deposit, without any call to the aspect in the source.

History and Where It Is Used

PostSharp is used in enterprise .NET applications to remove boilerplate for logging, caching, threading, INotifyPropertyChanged and contracts. Alternatives include Fody and Castle DynamicProxy, and the .NET compiler now supports source generators for some of the same jobs.

Learn More