Friday, September 15, 2006

PostSharp as Aspector?

Earlier I talked about "Aspector" - component of DataObjects.Net 4.0 that should inject proxy code directly into assemblies with persistent types. But recently we've found PostSharp - http://www.postsharp.org/projects/postsharp, and quite probably we'll use it instead of developing our own component. Currently I'm not sure if it will cover all our needs, but by the first look it covers may be 80% of them.

So what features we want to use?

Aspect code injection:

  • Possibility to apply aspects on any method type (incl. private \ internal methods, property getters \ setters, constructors, etc.)
  • Possibility to inject prologue \ epilogue as invocation of corresponding method
  • Possibility to pass complete method call information into prologue \ epilogue methods
  • Exception handling support in epilogue
Aspect binding:
  • "Apector Extender" concept: Aspector "applies" all discovered IAspectorExtenders to each class \ method in processed assembly
  • IAspectorExtender declares two key methods: ApplyAspects(SomeTypeInfp ti), ApplyAspects(SomeMethodInfp mi). These methods are invoked for each class \ method in processed assembly
  • Obviously there should be an API allowing to "apply" the aspect to any method in processed assembly. Something like Aspector.ApplyAspect(SomeMethodInfo mi; MethodInfo prologue; MethodInfo epilogue)
  • Aspector locates (loads) extenders based on:
    - Assembly-level attributes of processed assembly or on its references. E.g. [AspectorExtender(typeof(MyExtender), ExtenderBindingType.BindToDependentAssemblies)]
    - Type\method-level attributes applied to any type in processed assembly, as well as to its base types \ supported interfaces (e.g. [AspectorExtender(Type extenderType, ExtenderBindingType.BindToTarget | ExtenderBindingType.BindToDescendants)]
Other:
  • Appropriate modification .PDB files along with processed assemblies - it should be possible to debug any "aspected" assembly as before
  • Generics support - it should be possible to add aspects to generic types and methods
  • Possibility to distinguish top-level and base method calls (for virtual and overridden methods). Normally aspect code shouldn't be invoked when base method is called from overridden one, although both of them may contain the same injected code of prologue \ epilogue method invocation.
Let's look on unified (but rough) code of "aspected" method:
public SomeType M(SomeType1 P1, SomeType2 P2, ...)
{
  MethodInvocationDescriptor mid =
    new MethodInvocationDescriptor(this,
      "public SomeType M(SomeType1, SomeType2)",
      new object[] {P1, P2});
  if (!mid.IsBase)
    ISomeExtender.Prologue(mid);
  try {
    // Original method body goes here
  }
  catch (ExceptionType1 e1) {
    mid.Exception = e1;
    if (!mid.IsBase)
      ISomeExtender.Epilogue(mid);
    if (mid.Exception==null)
      return (SomeType)mid.Result;
    else
      throw;
  }
  catch (ExceptionType2 e2) {
    // Similar exception processing block goes here
  }
  finally {
    if (!mid.IsBase && !mid.IsEpilogueInvoked)
      ISomeExtender.Epilogue(mid);
  }
}
Notes:
  • Prologue and epilogue may throw an exception
  • Probably it is also desirable to "push" method return value to MethodInvocationDescriptor before invoking Epilogue, but this implies modification of original method body (replacement of all return statements).

4 comments:

  1. Does anyone knows how to publish code keeping its formatting here?

    ReplyDelete
  2. Alex,

    I am the main author of PostSharp. I am pleased that you consider using it for your code weaving. I wanted to let you know that I am looking forward to helping you for this and if you are missing some feature we can work together on this (if you need it, others will need it also).

    Do not hesitate to contact me personally (gael at fraiteur dot net).

    Kind Regards,

    Gael Fraiteur

    ReplyDelete
  3. Hello Gael,

    Many thanks for your proposal - I was even a bit astonished by it (mainly because I created this blog just few days ago). You developing a great tool!

    We'll evaluate PostSharp deeper on the next week, and as result, will derive a list of features we missing. We'll be very glad to help implementing them in PostSharp.

    ReplyDelete
  4. Quick status: it looks like PostSharp is almost exactly the tool we wanted to develop - it allows to do all we need, and even much more!

    Gael, many thanks for developing it, as well as for your help!

    ReplyDelete