PostSharp Blog

The official blog of PostSharp: annoucements, tips & tricks

General
24 December 2008

VIP Content

If you want to present PostSharp to your user group or at a conference, we can help you with presentation material. Please register as a VIP member.

Who can be a VIP member?

VIP members are all UG team leaders, conference organizers, speakers, or technical writers.

How to become a VIP member?

You have to register on our forum, then request for membership using the private messaging facility. Please describe the reason why you are eligible and a link to a public page proving your claim.

What is in the VIP section?

Presentation material for speakers (PowerPoint slides and code samples).

Why is this material not public?

Put yourself in the audience's shoes. Would you want to served a talk that is publically available on the internet? Surely not. However, it is impossible to make new slides for every talk. Therefore we make them available for speakers so they can get inspired and copy-paste some figures, while keeping track of what was delivered to which audience.

General
24 December 2008

PostSharp in Your .NET User Group

Do you want to hear about PostSharp at your .NET User Group? Suggest your DNUG leader to invite Gael Fraiteur, PostSharp's project leader.

As long as the event is public and free for participants, we come for free. Our sessions are generally are generally well quoted.

For details, ask community@codingglove.com.

General
24 December 2008

PostSharp in Your Company

As a part of their general policies, many companies organize regular workshops to introduce their employees to new technologies and approaches.

As the creators of PostSharp, Coding Glove can give you a unique introduction to aspect-oriented programming (AOP) directly from the horse's mouth. Our workshops are not limited to PostSharp, but give keys to understand the foundations of AOP and to the differences in major frameworks (Spring.NET, Castle, MS PIA, PostSharp).

We always use excellently prepared materials and flavor them according to customer's specific expectations.

We can give talks in English, French, or Czech.

Please contact Coding Glove at sales@codingglove.com for details.

For public .NET user groups and code camps, we can provide this workshop or conference sessions for free.
General
24 December 2008

Conferences & User Groups

.NET Rocks

.NET Rocks!.NET Rocks, the Internet Audio Talk Show for .NET Developers (Carl Franklin, Richard Campbell, Gael Fraiteur).

ECOOP 2007

ECOOP 200721st European Conference on Object-Oriented Programming, July 30 - August 03, 2007, Berlin, Germany (Gael Fraiteur)

Netherlands SDE December 2007

Netherlands SDE December 2007Software Development Event December 2007, December 14, 2007, Amsterdam, Netherland (Pieter Joost vd Sande & Andre Boonzaaijer)

AOSD 2008

AOSD 20087th International Conference on Aspect-Oriented Software Development, March 31 - April 4, 2008, Brussels, Belgium (Gael Fraiteur)

Software Engineering Today 2008

SET 2008Software Engineering Today 2008, May 6-7, 2008, Zurich, Switzerland (Ralf Westphal)

Software Architect 2008

Software Architect 2008Software Architect 2008, June 3-5, 2008, London/UK (Ralf Westphal)

1st Polish Code Camp, June 2008

1st Polish Code CampPolish Code Kamp, June 8, 2008, Krakow, Poland (Gael Fraiteur)

Netherlands SDE June 2008

Netherlands SDE June 2007Software Development Event June 2008, June 22, 2008, Amsterdam, Netherland (Gael Fraiteur)

Zine Day 2008

Zine Day 2008Zine Day 2008, September 6, 2008, Warsaw, Poland (Gael Fraiteur)

Port Elizabeth .NET

Port Elizabeth 2008Port Elizabeth .NET, September 6, 2008, Port Elizabeth, South Africa (Simon Stewart)

Czech .NET Workshop

Czech .NET WorkshopsCzech .NET Workshop, September 9, 2008, Prague, Czech Republic (Gael Fraiteur)

Sweden .NET User Group (SweNug)

Sweden .NET User Group (SweNug)Sweden .NET User Group (SweNug), September 23rd, 2008, Stockholm, Sweden (Gael Fraiteur)

PRIO Conference

PRIO ConferencePRIO Conference, November 10-11, 2008, Baden-Baden, Germany (Gael Fraiteur)

Chicago Code Camp

Chicago Code CampChicago Code Camp, May 30th, 2009, Chicago, USA (Michael Hall)

Dev4Devs Johannesburg

Dev4DevsDev4Devs, May 9th, 2009, Johannesburg, South Africa (Simon Stewart)
General
12 December 2008

PostSharp Community

PostSharp is used daily by thousands of professional .NET developers around the world. This web site is the place they meet, exchange ideas, or seek or offer help.

General
12 December 2008

Transparent proxies, RealProxy and ContextBoundObject

The idea here is to put a proxy between the woven class and the consumer. It uses the same mechanism as in remoting: the client 'see' the remote object, but it actually talks to its proxy. All accesses to the aspected object go through the proxy class. The aspect is implemented as a transparent proxy, derived from the System.Runtime.Remoting.Proxies.RealProxy class.

There are tree ways to tell that an object should be accessed to a proxy:

  • If the aspected class is derived from ContextBoundObject, apply the System.Runtime.Remoting.Proxies.ProxyAttribute to this class in order to specify which proxy class should be used.
  • If the aspected class is derived from MarshalByRefObject, the method RealProxy.GetTransparentProxy() can be called in order to retrieve the proxy of an existing instance. But this means that user code cannot use constructors to get instances of aspected objects, but should use instead factory methods.
  • Otherwise, the aspected class should expose all its semantics on an interface.

These methods have thus the disadvantages of restricting the aspectable methods to instance methods of classed derived from ContextBoundObject or MarshalByRefObject. What is more, the only possible join points are method boundaries, as with the previous approach.

Tools:

Load-Time Static Weaving

This approach is very similar to Compile-Time Weaving, but occurs it occurs at runtime just before the assembly is loaded in memory. This situation is adequate when changing the aspects can require the application to be restarted. In its pure application, it does not enable a true dynamic weaving. PostSharp fully supports this scenario.

A variant of this approach is to add join point to code using static weaving, but add advices to join points at runtime, i.e. without restarting the application. It is not difficult to realize this using PostSharp, but it is not ready as an out-of-the-box feature. The disadvantage of this variant is of course that one should choose a balance between join point density (and so flexibility) and performance. Too many join points will produce a huge and slow code.

Tools:

Static Weaving with Dynamic Advices

The code is modified using Compile-Time Weaving techniques (eventually done at load-time, see above) so that 'hooks' are called at some locations. What the hooks really do can be changed at runtime.

Tools:

JIT Emission of Classes

This approach works only with public virtual methods and with interfaces. There are two approaches: the first is to generate a proxy class implementing the semantics of an interface. In this case, only interface methods can be aspected. The second approach is to generate a child class inherited from the aspected class; it requires this class to be unsealed and it is limited to virtual methods.

The System.Reflection.Emit namespace can be used. Besides of being limited to interface or virtual methods, this approach only supports the join points located at method boundaries (on entry, on exit, on exception).

Tools:

Profiler API

The Unmanaged Profiler API of the .NET Framework is initially intended to instrument the code, typically for memory and processor consumption. The same API can be used to execute virtually any code. Since the granularity of the Profiler API is very fine, it is possible to define a large range of join points. The outcome however is that the code has to be executed besides the profiler, which is not aimed to be used in production. This makes this approach inappropriate for commercial software.

Debugger API & Edit and Continue

The idea here is partially similar to the use of the Profiler API, but additionally the edit-and-continue facility can be used to modify MSIL code at runtime. This has the potential to get faster code than with the Profiler API. However, it has the same disadvantages, that is, it is little appropriate for commercial software.

Tools:

 

General
12 December 2008

Programmatic Tipping

Aspects can be added to fields, methods and types programmatically, i.e. using a compiled imperative programming language.

PostSharp Laos uses this approach for Compound Aspects. Here is an example from the Binding Sample:

public override void ProvideAspects(object targetElement, 
    LaosReflectionAspectCollection collection)
{  
  // Get the target type.  Type targetType = (Type) targetElement;
  // On the type, add a Composition aspect to implement 
  // the IBindable interface.

  collection.AddAspect(targetType, new AddBindableInterfaceSubAspect());   

  // Add a OnMethodBoundaryAspect on each writable non-static property.  
  foreach (PropertyInfo property in targetType.GetProperties())  
  {   
     if (property.DeclaringType == targetType &&
          property.CanWrite )   
      {    
          MethodInfo method = property.GetSetMethod();               
          if (!method.IsStatic)      
            collection.AddAspect(method, 
                    new OnPropertySetSubAspect(property.Name, this));    
       }  
  } 
} 

Programmatic tipping is also by high-level code weavers that assemble aspects from many low-level advices.

General
12 December 2008

Policy Injection

The term Policy Injection has been introduced recently by the Microsoft Patterns & Practices Team (see the blog of Ed Jeziersky and Tom Hollander) to designate what is fundamentally Aspect-Oriented Programming.

When asked why the name Policy Injection and not AOP, Ed answers:

... the reality is most of our customers have not heard of AOP or AOSD. Please put yourself in their shoes for a second. We wanted a name that was reflective of the use and benefit the block brings, rather than using an unfamiliar term that only the exceptions understand. We also wanted to have no implicit expectations on the design that may be inherited from AO solutions.

So Policy Injection is AOP, or at least a part of it. The reason why Microsoft did not choose the term AOP seems to be that AOP could have been perceived as a boring academic concept, which was fashionable in the .NET community about year 2003.


General
12 December 2008

MSIL Injection

MSIL Injection, or MSIL Insertion, is the process of modifying the MSIL instructions of an existing method. One says that we inject, or insert new instructions into an existing flow.

Injecting IL instructions is just a part of IL-level weaving. Modifying an existing code requires the following tasks to be done:

  1. Reading the metadata of the .NET module.
  2. Decoding the stream of IL instructions in a meaningful way.
  3. Detecting the points where new instructions should be injected.
  4. Restructuring the method body if exception handlers have to be added.
  5. Injecting IL instructions properly speaking.
  6. Assembling back the in-memory representation to a binary file.

These tasks are performed by an IL reader/writer, excepted the task 3 (detection of injection points), which is typically the task of the code weaver.

How to inject MSIL instructions?

If you are decided to inject directly MSIL instructions, prepare a stock of aspirins and eventually prepare your girlfriend to being absent from home. Then you may choose between the following approaches.

Standard System.Reflection/System.Reflection.Emit API

Since it ships with the .NET Framework, why not to use it? Well, these APIes seem adequate to create brandly new classes and methods, but are less appropriate to properly inject instructions, that is, modify an existing method. The principal problem is that the API is strictly stream oriented: you have to write the whole method in a single pass. This is not always feasible and is never easy.

Another problem is that the System.Reflection API does not give an exact image of a .NET module. It could cover 99% of your needs, but you will not have the possibility to support the last percent. For instance, System.Reflection does not make the difference between void* and System.IntPtr or int32 and System.Int32. Other advanced features like security attributes or marshaling may have an incomplete support.

Mono Cecil

Mono Cecil is a valid choice if you are looking for an IL reader/writer. It has a solid community and some commercial applications, which is a good assurance of quality. Even if the project is related to Mono, it supports also the Microsoft implementation. Read more on http://www.mono-project.com/Cecil.

PostSharp

PostSharp contains a IL reader/writer that covers the complete .NET specification for managed code. The APIes are optimized for high usability, so some users say it is easier to use than Cecil. The greater difference with Cecil is that PostSharp is designed as a platform where the IL reader/writer is only one component. The platform takes in charge the complete post-compilation process, including the integration with MSBuild, and offers a lot of additional services typically used by code weavers (type hierarchy analysis, use/used by analysis, ...).

Microsoft Phoenix

Phoenix is the new framework for the next generation of compilers at Microsoft. It abstracts the target machine, so it can work with MSIL assembly as well as Intel x86 assembly. Some users say that the price to pay is a greater complexity. The greatest advantage is of course the certainty of support and continuity. But pay attention to the license, it is currently reserved for academical research.

Rail

The initial aim of Rail is to implement an API that allows CLR assemblies to be manipulated and instrumented before they are loaded and executed. It uses static weaving of IL instructions. The APIes of Rail are often used as an IL reader/writer with some more advanced weaving capabilities. More on http://rail.dei.uc.pt/.

General
12 December 2008

Extending the Language

The most popular approach so far has been to define extensions to the base language, i.e. a new language based on the language of the aspected code. The de-facto standard in the Java culture is AspectJ. The following example is taken from the AspectJ Programming Guide:

 1 aspect FaultHandler {
 2
 3   private boolean Server.disabled = false;
 4
 5   private void reportFault() {
 6     System.out.println("Failure! Please fix it.");
 7   }
 8
 9   public static void fixServer(Server s) {
10     s.disabled = false;
11   }
12
13   pointcut services(Server s): target(s) && call(public * *(..));
14
15   before(Server s): services(s) {
16     if (s.disabled) throw new DisabledException();
17   }
18
19   after(Server s) throwing (FaultException e): services(s) {
20     s.disabled = true;
21     reportFault();
22   }
23 }

As you can see, lines 3-11 is pure Java but 13-22 use the AspectJ extension. Even if the purpose of this section is not to explain the AspectJ syntax, note the pointcut, before and after keywords.

The advantage of this approach is that the semantics of the language adapted on purpose, so the resulting code is clean and consistent. No 'trick'. A drawback is that this approach is language-dependent, if your aim is to develop a weaver, you have to develop a code enhancer for every targeted language. See the Compile-Time Weaving techniques for details. A weaver developer should also ideally provide integration with the IDE (Intellisense).

It is not possible to write an aspect weaver of this type using PostSharp, because PostSharp supposes that the code has already been compiled. Also, Runtime Weaving techniques are all unadapted for this scenario.