Iowa Code Camp 2009 - Introduction to AOP with PostSharp: Michael Hall

just3ws.com

AOP

Some things don't quite fit the domain. (Cross-cutting concerns, plumbing.)

Terms

Separation of concerns
- keep code focused on functional concerns
Aspect
- code module to implement requirements of a cross-cutting concern (class)
Advice
- code that will be executed (method)
Pointcut
- query to find desired join points
Join point
- where the advice is applied
Applied advice
- before, after, instead of (method body)

PostSharp

postsharp.org

Free - use PostSharp.Laos (open source but business-friendly) (.Core is GPL)

Integrates with Visual Studio, MSBuild, NAnt

Example

    
    [Serializable]  // required
    public class DemoAspectAttribute  // use Aspect by convention
      : PostSharp.Laos.OnMethodBoundaryAspect
    {
      public override void OnEntry(MethodExecutionEventArgs args)
      {
        Console.WriteLine("{0}#{1}({2})",
          args.Method.DeclaringType.Name,
          args.Method.Name,
          args.GetReadOnlyArgumentArray().Join());
      }

      // Can also override OnExit() and OnException().
    }

    [DemoAspect]  // if want to explicitly apply
    public class Foo ...
      // Aspect now applies to every method in class (even ctor).

    // Can assign/filter at assembly level, too!
    [assembly:DemoAspect(AttributeTargetTypes="Demo.Core.Aspects.*",
                         AttributeReplace=true,  // optional filter
                         AttributeExclude=true,  // optional filter
                         AttributePriority=99)]
    
    

Use judiciously

Overuse of logging, etc. can affect performance.

Can also alter behavior; they do let you shoot yourself in the foot.

Since aspects are compiled in (IL weaving), you're "stuck" with what you put in (until recompile).

Can affect compilation speed (30%).

Usage

Reference PostSharp.Laos and PostSharp.Public.

Override CompileTimeInitialize() in aspect if want to cache things like method name, assembly name, etc.

May want to put assembly directives in an AspectMapping.cs file - can comment out to remove applying aspects.

Best to put attribute in separate namespace to make it easy to exclude. Don't want to apply the aspect to itself (compiler error).

May want to exclude Dispose methods when applying aspects.

Actually adjusts line numbers in PDB to go to right breakpoint! Can even step through aspect code in debugger.

Composition Aspect

Can do mix-ins - make class implement an interface on-the-fly and provide a concrete implementation.

Basically multiple inheritance.

Note that IntelliSense may complain if cast to interface, but it'll work.

Great for generated code.


Your Host: webmaster@truewill.net
Copyright © 2009 by William Sorensen. All rights reserved.