Execute PostSharp at runtime

by Gael Fraiteur on 16 Nov 2006

Like week-end I have been working on a breaking feature of PostSharp: the possibility to use it at runtime. So PostSharp is not only a post-compiler any more

Of course, the core technology is still and will stay MSIL manipulation. When I say that PostSharp can be used at runtime, I mean that .NET modules can be woven just before they are loaded by the Virtual Runtime Engine (VRE). After they have been loaded, they cannot be modified. Obviously.

Why at runtime?

Weaving an assembly at runtime makes sense principally within application servers. These servers typically offer services like transactions or persistence. These aspects may be defined, for instance, at deployment time in a management console. So they have to be woven outside the development environment.

How does it work?

If you liked the Platform Infrastructure (what makes PostSharp really different from an ordinary IL reader/writer), you will have another reason to be satisfied: the same infrastructure is now available at runtime. It has been redesigned to make no difference between runtime and compile-time use. The MSBuild task and the command-line utility have been corrected to use the new design.

Concretely, I defined a new object PostSharpObject that is the entry point for the Platform Infrastructure. You can create an instance (either in the current AppDomain either in a private one) using the PostSharpObjectFactory -- in any case you will only get the interface IPostSharpObjectFactory. This interface has a single method InvokeProjects, that allows to execute a set of project. Each project has its own source module and its own properties. This satisfies most compile-time scenarios and even some runtime ones!

Things become more interesting when you need to weave assembly in deep-first order. That means that you need to weave referred assemblies first, then referring. This is typically the case when you need to change the public interface of assemblies (for instance change fields into properties). In this case, you have to implement the new IPostSharpHost interface. This interface is called every time an assembly reference should be resolved. You get the opportunity to tell how assemblies should be processed, i.e. you can ask there to transform it using a project and given parameters.

On the other extreme, lazy weaving of assemblies (weave just before the assembly is required by the VRE) needs a more complex interaction between the host and PostSharp. The host has to implement the AppDomain.AssemblyResolve event.

Do you want to try?

The changes have been merged in the trunk of the SVN repository. I have built a prerelease of the 1.0 Beta 1 version. It is largely documented and I wrote a sample.

Feedback welcome!