I have just checked in a library (actually, only two classes) allowing to use PostSharp in ASP.NET projects. The stuff is hosted at http://code.google.com/p/postsharp-user-plugins/. The reason why it did not work previously is that ASP.NET compilation does not go through MSBuild, so PostSharp was simply not invoked.

Indeed, MSBuild has its own compilation mechanism. Fortunately, it has an extension point that seems just done for PostSharp: the IAssemblyPostProcessor interface. As you may imagine, it allows to post-process the compiled assembly.

So I simply developed an implementation of this interface (one class). The second class is a configuration handler.

Here is how to use this preliminary version of the library (from the documentation):

In order to use PostSharp in a web project, specify this class as an assembly post-processor in web.config:

<configuration>
     <system.web>
       <compilation debug="true"
         assemblyPostProcessorType="PostSharp.AspNet.AssemblyPostProcessor, PostSharp.AspNet"/>
     </system.web>
</configuration>

Additionally, you have to add the <postsharp ... /> section in the configuration file:

<?xml version="1.0"?>
<configuration>
 <!-- Add a configuration handler for PostSharp. -->
 <configSections>
  <section name="postsharp"
                         type="PostSharp.AspNet.Configuration.PostSharpConfiguration, PostSharp.AspNet"/>
 </configSections>
 <!-- PostSharp configuration -->
 <postsharp directory="P:\open\branches\1.0\Core\PostSharp.MSBuild\bin\Debug" trace="true">
  <parameters>
   <!--<add name="parameter-name" value="parameter-value"/>-->
  </parameters>
  <searchPath>
   <!-- Always add the binary folder to the search path. -->
   <add name="bin" value="~\bin"/>
   <!-- Then add the location of plug-ins that are not installed in standard locations. -->
   <add name="laos-weaver" value="P:\open\branches\1.0\Laos\PostSharp.Laos.Weaver\bin\Debug"/>
  </searchPath>
 </postsharp>
 <appSettings/>
 <connectionStrings/>
 <system.web>
  <!-- Note the 'assemblyPostProcessorType' attribute. -->
  <compilation debug="true"
                             assemblyPostProcessorType="PostSharp.AspNet.AssemblyPostProcessor, PostSharp.AspNet">
  <authentication mode="None"/>
  <trace enabled="true" pageOutput="true"/>
 </system.web>
</configuration>
 

In all configuration parameters and in search path elements, the tilde character (~) is replaced by the physical path of the application.

Be prepared that the compilation will be much much longer, especially if it is fine-grained...

This is a preliminary version, feedback is welcome!

Happy postsharping!

Gael

PostSharp4Unity modifies assemblies after compilation to make objects self-configurable: you don't need to call a factory method; you can use the default constructor. All you have to do is to decorate your class with the custom attribute "Configurable". It smells like Spring, isn't it ;-). It is available from http://code.google.com/p/postsharp-user-plugins/. I have updated the StopLight sample. The first change is on the StoplightForm class:
[Configurable]
public partial class StoplightForm : Form, IStoplightView
  {
Then, in Program.Main, you can use the default constructor:
Application.Run(new StoplightForm());
Unfortunately, that's not all. Since Unity has no notion of context registry (i.e. no notion of "current container"), you have to build a basic one:
public sealed class UnityContainerProvider : IUnityContainerProvider
{
   private readonly IUnityContainer container;
  
    public UnityContainerProvider()
    {
       this.container = new UnityContainer()
         .Register<ILogger, TraceLogger>()
         .Register<IStoplightTimer, RealTimeTimer>();
    }

    public IUnityContainer  CurrentContainer
     { get { return this.container; } }
}  
Then tell PostSharp4Unity to build your container:
[assembly: DefaultUnityContainerProvider(
  typeof(UnityContainerProvider))]
As you can see, there is a little of set up to do, but it's only once per assembly. (And would be useless if there were some Unity-wide notion of context registry or default container.) At this price, you can use Unity with any object without having to construct them using a factory method. Pay attention that your 'configurable' objects are now configured before the constructor is executed, and not after. So, in the class StoplightForm, we have to move the view initialization at the end of the constructor:
[Configurable]
public partial class StoplightForm : Form, IStoplightView
{
   private StoplightPresenter presenter;

   public StoplightForm()
   {
      InitializeComponent();
      presenter.SetView(this);
    }

   [Dependency]
    public StoplightPresenter Presenter
    {
      get { return presenter; }
      set { presenter = value; }
    }
There are still some problems being discussed, but at least you have the first bits. Happy PostSharping! Gael

I have been quite laconic in the release announcement about relicensing. Much more was said on the licensing page, but yet I got some feedback that it was not clear.

The summary of PostSharp licensing is: Runtime libraries are released under the non-viral LGPL license; compile-time components are released under GPL.

The first thing to realize is that chances are great that relicensing changes nothing to your life. Indeed, programs that are transformed by PostSharp are not contaminated by GPL, since they reference only runtime libraries of PostSharp. Basically, if your program does not need the library PostSharp.Core.dll to be present on your customer's computer, using PostSharp does not affect your program's licensing scheme at all. And I'm pretty sure it's the case of 99% of users.

So who is impacted by the GPL license? Well, people who develop programs that use PostSharp to modify other assemblies. In other words: if your program transform the programs of your customers, read on.

Anyway, what kind of programs modify other programs? There are two typical families of products that fall in that category: O-R mappers, obfuscators, optimizers, code generators are the first one; they are typically deployed only on development machines. Another family includes application servers offering aspect-oriented services (AFAIK there is none for .NET, but in the Java world it's quite common for an application server to have an integrated AOP engine). Of course a special member of that family is the still-unreleased Starcounter object database server; deploying .NET assemblies to this server will make classes "magically" persistent in a server environment.

What if your program uses core parts of PostSharp? Actually, you are not automatically infected by GPL. You have the following options:

  • If you don't distribute your work outside of your company, you are not infected. So if you make an in-house plug-in, you are okay.
  • You can release your work under any license approved by the Open Source Initiative. Well, attention: all your work, and not only the assembly directly referencing PostSharp.
  • You can acquire a commercial license, which is basically a GPL exemption for your products. Exemptions will be provided on an individual, per-product basis. Since the number of customer of these licenses is quite small, exemptions will be given as a part of a partnership program including support and NDA. The idea there is to have a few good customers with a strong relationship. The "masses" have the product for free (anyway with a level of support often quoted as better than commercial one).

An important point is that the licensing itself is in 'candidate' phase. If it makes you feel badly, do not hesitate to react. The point is that, given the size and the complexity of the product, it is not possible any more to develop and support it exclusively during free time, so I must raise some money. I would like the product to be supported by few key partners having a strong interest in PostSharp, and let it free for most (99%) people.

Happy PostSharping!

Gael